Reputation: 23177
This is my first real attempt at using multithreading, I want to know how I can tell when all of my tasks groups are done running:
for (int i = 0; i < taskGroups.Count(); i++) {
ThreadStart t = delegate { RunThread(taskGroups[i]); };
new Thread(t).Start();
}
if(allThreadsComplete){ //???
}
Any help would be much appreciated
Addendum:
ThreadStart[] threads = new ThreadStart[taskGroups.Count()];
for (int i = 0; i < taskGroups.Count(); i++) {
threads[i] = new ThreadStart[]
threads[i] = delegate { RunThread(taskGroups[i]); };
new Thread(t).Start();
}
bool threadsComplete = false;
while(!threadsComplete){
for(int i=0;i<taskGroups.Count();i++){
if(threads[i].State == complete)
threadsComplete = true;
}
}
Upvotes: 3
Views: 4567
Reputation: 40345
If you're using 3.5 then you can write your own CountdownEvent, if you're using 4.0 then you can use the built in CountdownEvent to do something like this:
CountdownEvent = new CountdownEvent(taskGroups.Count());
for (int i = 0; i < taskGroups.Count(); i++)
{
int item = i; // copy i locally
ThreadStart t = delegate
{
RunThread(taskGroups[item]);
latch.Signal();
};
new Thread(t).Start();
}
latch.Wait();
The latch.Wait()
will cause your code to block until the threads have all finished. Furthermore, you might want to change the way you start your thread a bit:
CountdownEvent = new CountdownEvent(taskGroups.Count());
for (int i = 0; i < taskGroups.Count(); i++)
{
int item = i; // copy i locally
Thread t = new Thread(()=>
{
RunThread(taskGroups[item]);
latch.Signal();
});
t.IsBackground = true;
t.Start();
}
latch.Wait();
Note that I'm setting the thread to background: this your application from hanging when exit and not all threads have finished (i.e. prevents ghost or daemon threads).
Upvotes: 1
Reputation: 26485
You need to store all your threads, and then call Thread.Join().
Something like this:
List<Thread> threads = new List<Thread>();
for (int i = 0; i < taskGroups.Count(); i++) {
int temp = i; //This fixes the issue with i being shared
Thread thread = new Thread(() => RunThread(taskGroups[temp]));
threads.Add(thread);
thread.Start();
}
foreach (var thread in threads) {
thread.Join();
}
Upvotes: 4
Reputation: 13019
First of all consider switching to the new asynchronous pattern using Task
.
Anyway if you want to wait for all your threads you can call Thread.Join
:
var threads = new List<Thread>();
for (int i = 0; i < taskGroups.Count(); i++) {
ThreadStart t = delegate { RunThread(taskGroups[i]); };
var thread = new Thread(t);
threads.Add(thread);
thread.Start();
}
threads.ForEach(a => a.Join());
Remember that you can also pass a timeout parameter that will wait until the thread finishes only if it doesn't takes more than the time you passed in.
Upvotes: 0
Reputation: 66399
You can add public static integer field to the main thread, in each child thread increase it by one when it's completed then in the main thread wait (in a loop) until that variable is equal to the taskGroups.Count()
.
Upvotes: 0
Reputation: 30780
You can use Thread.Join to make sure that each individual thread has finished running.
Upvotes: 0