I have an application in which the user will choose to do a number of tasks along with the maximum number of threads. Each task should run on a separate thread. Here is what I am looking for:
If the user specified "n less than t" where n is the maximum number of threads and t is the number of tasks. The program should run "n" threads and after they finish, the program should be notified by some way and repeat the loop untill all tasks are done.
My Question is:
How to know that all running threads has finished their job so that I can repeat the loop.
I recommend using the ThreadPool for your task. Its algorithm will generally be more efficient than something you can roll by hand.
Now the fun part is getting notified when all of your threads complete. Unless you have really specific needs which make this solution unsuitable, it should be easy enough to implement with the CountdownEvent class, which is a special kind of waithandle that waits until its been signaled n times. Here's an example:
using System;
using System.Linq;
using System.Threading;
using System.Diagnostics;
namespace CSharpSandbox
{
class Program
{
static void SomeTask(int sleepInterval, CountdownEvent countDown)
{
try
{
// pretend this did something more profound
Thread.Sleep(sleepInterval);
}
finally
{
// need to signal in a finally block, otherwise an exception may occur and prevent
// this from being signaled
countDown.Signal();
}
}
static CountdownEvent StartTasks(int count)
{
Random rnd = new Random();
CountdownEvent countDown = new CountdownEvent(count);
for (int i = 0; i < count; i++)
{
ThreadPool.QueueUserWorkItem(_ => SomeTask(rnd.Next(100), countDown));
}
return countDown;
}
public static void Main(string[] args)
{
Console.WriteLine("Starting. . .");
var stopWatch = Stopwatch.StartNew();
using(CountdownEvent countdownEvent = StartTasks(100))
{
countdownEvent.Wait();
// waits until the countdownEvent is signalled 100 times
}
stopWatch.Stop();
Console.WriteLine("Done! Elapsed time: {0} milliseconds", stopWatch.Elapsed.TotalMilliseconds);
}
}
}
You probably want to use a Thread Pool for this. You (can) specify the number of threads in the pool, and give it tasks to do. When a thread in the pool is idle, it automatically looks for another task to carry out.
If you want to do this without the thread pool, you can use Thread.Join to wait for the threads to complete. That is:
Thread t1 = new Thread(...);
Thread t2 = new Thread(...);
t1.Start();
t2.Start();
// Wait for threads to finish
t1.Join();
t2.Join();
// At this point, all threads are done.
Of course, if this is an interactive application you'd want that to happen in a thread itself. And if you wanted to get fancy, the waiting thread could do the work of one of the threads (i.e. you'd start thread 1 and then the main thread would do the work of the second thread).
If this is an interactive application, then you probably want to make use of BackgroundWorker (which used the thread pool). If you attach an event handler to the RunWorkCompleted event, then you will be notified when the worker has completed its task. If you have multiple workers, have a single RunWorkCompleted event handler, and keep track of which workers have signaled. When they've all signaled, then your program can go ahead and do whatever else it needs to do.
The example at http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx should give you a good start.
Could you check the isAlive() value for each thread? if all values equal false then you would know that all your threads have ended. Additionally, there is a way to have your delegate return it's own status.
http://msdn.microsoft.com/en-us/library/system.threading.thread.isalive(v=VS.90).aspx
Related
I have a little c# app with multiple threads runing, but my main thread has to wait for all of threads to finish then it can do the rest.
problem now is that im using .join() for each thread, this seems wait for each thread to finish then it goes to next thread, which makes app not really multi-threading and take long time to finish.
so I wonder if there is any way I can get around this problem or just a way to check if there are no more threads is active.
thanks
If you're hanging on to the Thread object, you can use Thread.IsAlive.
Alternately, you might want to consider firing an event from your thread when it is done.
Thread.Join() doesn't mean your application isn't multithreaded - it tells the current thread to wait for the other thread to finish, which is exactly what you want.
Doing the following:
List<Thread> threads = new List<Thread>();
/** create each thread, Start() it, and add it to the list **/
foreach (Thread thread in threads)
{
thread.Join()
}
will continue to run the other threads, except the current/main thread (it will wait until the other threads are done).
Just use Thread.Join()
Ye, as said by Cuong Le, using Task Parallel Library would be much efficient.
However, you can Create a list of Threads and then check if they are alive or not.
var threadsList = new List<Thread>();
threadsList.Add(myThread); // to add
bool areDone = true;
foreach (Thread t in threadsList) {
if (t.IsAlive)
{
areDone = false;
break;
}
}
if (areDone)
{
// Everything is finished :O
}
Run multiple at same time but wanted to wait for all of them to finish, here's a way of doing the same with Parallel.ForEach:
var arrStr = new string[] {"1st", "2nd", "3rd"};
Parallel.ForEach<string>(arrStr, str =>
{
DoSomething(str); // your custom method you wanted to use
Debug.Print("Finished task for: " + str);
});
Debug.Print("All tasks finished");
That was the most simplest and efficient i guess it can go if in C# 4.0 if you want all tasks to run through same method
Try using BackgroundWorker
It raises an event in the main thread (RunWorkerCompleted) after its work is done
Here is one sample from previously answered question
https://stackoverflow.com/a/5551376/148697
I need to create 5 threads and associate an ArrayList with each thread .I have another thread which will read values from a queue (one by one) and push that message to the
ArrayList associated with each thread which i created earlier . Then that thread should read value from the ArrayList and start executing. How can I do that?
You can use the Monitor class to synchronize your threads. Here is an example using five different locks and queues, one for each thread, based on your comments.
It's important to protect with a lock any data shared between two different threads. Only the thread holding the lock should access the data.
The worker thread locks on its own personal object (in the syncs array), and, having the lock, then calls Monitor.Wait, which will release the lock.
The main thread may have already tried to lock that thread's sync object, or soon will, it doesn't matter because it won't have access to that thread's queue until it does have the lock. Then it is safe to queue up a message. The Monitor.Pulse call wakes up the waiting worker thread, but the worker stays stuck in its Monitor.Wait call until the main thread releases the lock (by falling out of the lock() { } code block.)
When Monitor.Wait returns to the worker, the lock will have been re-acquired.
You can't always assume that the threads will pulse and wake at the same rate, which is why I have the extra while loop in the worker thread, to handle the case where the main thread has signaled a few times with several messages before the worker actually woke up to process them.
This example is much simplified -- it doesn't cover shutting the workers down, for example, but it should give you some ideas get started.
namespace ConsoleApplication1
{
using System;
using System.Collections.Generic;
using System.Threading;
internal class Program
{
private static readonly Queue<int>[] queues = new Queue<int>[5];
private static readonly object[] syncs = new object[5];
public static void Main(string[] args)
{
for (int i = 0; i < 5; i++)
{
queues[i] = new Queue<int>();
syncs[i] = new object();
var thread = new Thread(ThreadProc);
thread.Start(i);
}
var random = new Random();
while (true)
{
Thread.Sleep(1000);
int index = random.Next(queues.Length);
lock (syncs[index])
{
int message = random.Next(100);
queues[index].Enqueue(message);
Console.WriteLine("Sending message " + message + " to thread at " + index);
Monitor.Pulse(syncs[index]);
}
}
}
private static void ThreadProc(object data)
{
var index = (int)data;
lock (syncs[index])
{
while (true)
{
while (queues[index].Count == 0)
{
Monitor.Wait(syncs[index]);
}
int message = queues[index].Dequeue();
Console.WriteLine("Thread at " + index + " received message " + message);
}
}
}
}
}
You cannot use array lists without synchronization, because the parceling thread (thread #6) will be writing to the places from which the other five would be reading. Using BlockingCollection is a good choice for your task.
Create and initialize an array of five BlockingCollection<T> objects, and pass each thread the index of its collection in the array through the parameter object. Each of the five "worker" threads should loop on the call to Take() on the blocking collection at the index passed at initialization, and do whatever they need to do. The work parceling thread should use Add to add values designated for each thread.
I know this doesn't directly answer what you're asking, but I'm just wondering if this idea might better fit what you're trying to do.
Rather than have an ArrayList for each thread, make the main queue a thread-safe queue System.Collections.Concurrent.ConcurrentQueue, and give each thread a reference to it. Then you don't need the other thread to hand-off the work to your worker threads.
Each worker thread can just check the queue to see if there is any work waiting. If so it grabs it and does it's processing. If not, the thread sleeps for a period before checking again.
This won't work well if specific threads need to handle specific types of values (and that's what your other thread is managing), but it should be reasonable for basic load sharing across a pool of workers.
As part of a windows service
I'm accepting incoming socket connection using
myListener.BeginAcceptSocket(acceptAsync, null)
The acceptAsync function executes on a seperate thread (just as expected).
When the service is requested to shutdown, I "signal" the threads that accepted and are currently working on the sockets, to finish up.
After signaling each thread to end,I need to block until they are all done. I have a list of threads, that I thought I could iterate through and Join each thread until they were all done.
Howerver it seems that these threads don't end, but return to the pool, so the Join will wait for ever.
How do I block until a thread is returned to the pool?
You shouldn't use Join in this case. Rather, you should use a series of WaitHandles (specifically, an AutoResetEvent or ManualResetEvent) which your threads will signal when they are done with their work.
You would then call the static WaitAll method on the WaitHandle class, passing all of the events to wait on.
The canonical pattern for doing this is to use a CountdownEvent. The main thread will increment the event to indicate that it is participating and the worker threads will do the same once they start. After the worker threads have finished they will decrement the event. When the main thread is ready to wait for completion it should decrement the event and then wait on it. If you are not using .NET 4.0 then you can get an implemention of a countdown event from part 4 of Joe Albahari's threading ebook.
public class Example
{
private CountdownEvent m_Finisher = new CountdownEvent(0);
public void MainThread()
{
m_Finisher.AddCount();
// Your stuff goes here.
// myListener.BeginAcceptSocket(OnAcceptSocket, null);
m_Finisher.Signal();
m_Finisher.Wait();
}
private void OnAcceptSocket(object state)
{
m_Finisher.AddCount()
try
{
// Your stuff goes here.
}
finally
{
m_Finisher.Signal();
}
}
}
The best way would be to change acceptAsync so that it signals on a semaphore, your main thread can then wait on that semaphore.
You don't have a lot of acces to or control over Threapool threads.
What does it mean when one says no polling is allowed when implimenting your thread solution since it's wasteful, it has latency and it's non-deterministic. Threads should not use polling to signal each other.
EDIT
Based on your answers so far, I believe my threading implementation (taken from: http://www.albahari.com/threading/part2.aspx#_AutoResetEvent) below is not using polling. Please correct me if I am wrong.
using System;
using System.Threading;
using System.Collections.Generic;
class ProducerConsumerQueue : IDisposable {
EventWaitHandle _wh = new AutoResetEvent (false);
Thread _worker;
readonly object _locker = new object();
Queue<string> _tasks = new Queue<string>();
public ProducerConsumerQueue() (
_worker = new Thread (Work);
_worker.Start();
}
public void EnqueueTask (string task) (
lock (_locker) _tasks.Enqueue (task);
_wh.Set();
}
public void Dispose() (
EnqueueTask (null); // Signal the consumer to exit.
_worker.Join(); // Wait for the consumer's thread to finish.
_wh.Close(); // Release any OS resources.
}
void Work() (
while (true)
{
string task = null;
lock (_locker)
if (_tasks.Count > 0)
{
task = _tasks.Dequeue();
if (task == null) return;
}
if (task != null)
{
Console.WriteLine ("Performing task: " + task);
Thread.Sleep (1000); // simulate work...
}
else
_wh.WaitOne(); // No more tasks - wait for a signal
}
}
}
Your question is very unclear, but typically "polling" refers to periodically checking for a condition, or sampling a value. For example:
while (true)
{
Task task = GetNextTask();
if (task != null)
{
task.Execute();
}
else
{
Thread.Sleep(5000); // Avoid tight-looping
}
}
Just sleeping is a relatively inefficient way of doing this - it's better if there's some coordination so that the thread can wake up immediately when something interesting happens, e.g. via Monitor.Wait/Pulse or Manual/AutoResetEvent... but depending on the context, that's not always possible.
In some contexts you may not want the thread to actually sleep - you may want it to become available for other work. For example, you might use a Timer of one sort or other to periodically poll a mailbox to see whether there's any incoming mail - but you don't need the thread to actually be sleeping when it's not checking; it can be reused by another thread-pool task.
Here you go: check out this website:
http://msdn.microsoft.com/en-us/library/dsw9f9ts%28VS.71%29.aspx
Synchronization Techniques
There are two approaches to synchronization, polling and using synchronization objects. Polling repeatedly checks the status of an asynchronous call from within a loop. Polling is the least efficient way to manage threads because it wastes resources by repeatedly checking the status of the various thread properties.
For example, the IsAlive property can be used when polling to see if a thread has exited. Use this property with caution because a thread that is alive is not necessarily running. You can use the thread's ThreadState property to get more detailed information about a thread's status. Because threads can be in more than one state at any given time, the value stored in ThreadState can be a combination of the values in the System.Threading.Threadstate enumeration. Consequently, you should carefully check all relevant thread states when polling. For example, if a thread's state indicates that it is not Running, it may be done. On the other hand, it may be suspended or sleeping.
Waiting for a Thread to Finish
The Thread.Join method is useful for determining if a thread has completed before starting another task. The Join method waits a specified amount of time for a thread to end. If the thread ends before the timeout, Join returns True; otherwise it returns False. For information on Join, see Thread.Join Method
Polling sacrifices many of the advantages of multithreading in return for control over the order that threads run. Because it is so inefficient, polling generally not recommended. A more efficient approach would use the Join method to control threads. Join causes a calling procedure to wait either until a thread is done or until the call times out if a timeout is specified. The name, join, is based on the idea that creating a new thread is a fork in the execution path. You use Join to merge separate execution paths into a single thread again
One point should be clear: Join is a synchronous or blocking call. Once you call Join or a wait method of a wait handle, the calling procedure stops and waits for the thread to signal that it is done.
Copy
Sub JoinThreads()
Dim Thread1 As New System.Threading.Thread(AddressOf SomeTask)
Thread1.Start()
Thread1.Join() ' Wait for the thread to finish.
MsgBox("Thread is done")
End Sub
These simple ways of controlling threads, which are useful when you are managing a small number of threads, are difficult to use with large projects. The next section discusses some advanced techniques you can use to synchronize threads.
Hope this helps.
PK
Polling can be used in reference to the four asyncronous patterns .NET uses for delegate execution.
The 4 types (I've taken these descriptions from this well explained answer) are:
Polling: waiting in a loop for IAsyncResult.Completed to be true
I'll call you
You call me
I don't care what happens (fire and forget)
So for an example of 1:
Action<IAsyncResult> myAction = (IAsyncResult ar) =>
{
// Send Nigerian Prince emails
Console.WriteLine("Starting task");
Thread.Sleep(2000);
// Finished
Console.WriteLine("Finished task");
};
IAsyncResult result = myAction.BeginInvoke(null,null,null);
while (!result.IsCompleted)
{
// Do something while you wait
Console.WriteLine("I'm waiting...");
}
There's alternative ways of polling, but in general it means "I we there yet", "I we there yet", "I we there yet"
What does it mean when one says no
polling is allowed when implimenting
your thread solution since it's
wasteful, it has latency and it's
non-deterministic. Threads should not
use polling to signal each other.
I would have to see the context in which this statement was made to express an opinion on it either way. However, taken as-is it is patently false. Polling is a very common and very accepted strategy for signaling threads.
Pretty much all lock-free thread signaling strategies use polling in some form or another. This is clearly evident in how these strategies typically spin around in a loop until a certain condition is met.
The most frequently used scenario is the case of signaling a worker thread that it is time to terminate. The worker thread will periodically poll a bool flag at safe points to see if a shutdown was requested.
private volatile bool shutdownRequested;
void WorkerThread()
{
while (true)
{
// Do some work here.
// This is a safe point so see if a shutdown was requested.
if (shutdownRequested) break;
// Do some more work here.
}
}
I have a scenario when I start 3..10 threads with ThreadPool.
Each thread does its job and returns to the ThreadPool.
What are possible options to be notified in main thread when all background threads have finished?
Currently I'm using a homegrown method with incrementing a variable for each of created threads and decrementing it when a background thread is about to finish.
This works just fine, but I was curious if there are better options.
Decrementing a variable (between threads) is a little bit risky unless done with Interlocked.Decrement, but that approach should be fine if you have the last thread (i.e. when it gets to zero) raise an event. Note that it would have to be in a "finally" block to avoid losing it in the case of exceptions (plus you don't want to kill the process).
In "Parallel Extensions" (or with .NET 4.0), you might also look at the Parallel.ForEach options here... that might be another way of getting everything done as a block. Without having to watch them all manually.
Try this: https://bitbucket.org/nevdelap/poolguard
using (var poolGuard = new PoolGuard())
{
for (int i = 0; i < ...
{
ThreadPool.QueueUserWorkItem(ChildThread, poolGuard);
}
// Do stuff.
poolGuard.WaitOne();
// Do stuff that required the child threads to have ended.
void ChildThread(object state)
{
var poolGuard = state as PoolGuard;
if (poolGuard.TryEnter())
{
try
{
// Do stuff.
}
finally
{
poolGuard.Exit();
}
}
}
Multiple PoolGuards can be used in different ways to track when threads have ended, and handles threads that haven't started when the pool is already closed.
If its not more than 64 Threads to wait on, you can use the WaitHandle.WaitAll method like this:
List<WaitHandle> events = new List<WaitHandle>();
for (int i = 0; i < 64; i++)
{
ManualResetEvent mre = new ManualResetEvent(false);
ThreadPool.QueueUserWorkItem(
delegate(object o)
{
Thread.Sleep(TimeSpan.FromMinutes(1));
((ManualResetEvent)o).Set();
},mre);
events.Add(mre);
}
WaitHandle.WaitAll(events.ToArray());
The execution will wait till all ManualResetEvents are set, alternatively, you may use WaitAny method.
The WaitAny and WaitAll methods will block the execution, but you can simply use the list, or a dictionary of ManualResetEvents linked to the task that is spawn for later determining if the thread is done though.
There's isn't a built-in way to do this at the moment - I find it one of the biggest pains about using pool threads.
As Marc says, this is the kind of stuff which is being fixed in Parallel Extensions / .NET 4.0.
Couldn't you give each thread a distinct ManualResetEvent and have each set the event when done. Then, in the main thread you can wait on all the events passed in.
Marc's solution is best if you just want to know when all the jobs are finished, and don't need finer info than that (as seems to be your case).
If you wanted some thread to spawn jobs, and some other thread to to receive the notifications, you could use WaitHandle. The code is much longer.
int length = 10;
ManualResetEvent[] waits = new ManualResetEvent[length];
for ( int i = 0; i < length; i++ ) {
waits[i] = new ManualResetEvent( false );
ThreadPool.QueueUserWorkItem( (obj) => {
try {
} finally {
waits[i].Set();
}
} );
}
for ( int i = 0; i < length; i++ ) {
if ( !waits[i].WaitOne() )
break;
}
The WaitOne method, as written, always returns true, but I have written it like that to make you remember that some overloads take a Timeout as an argument.
What about using Semaphore, and set a limit to it as much as your thread pool. Have a method to fetch a Semaphore, to be called when you start your thread, release it when your thread end and raise an event if you've taken up all the Semaphore.