Coming from C#, I would probably use WaitHandle.WaitAll
. You can create an array of ManualResetEvent
objects (one for each task to be completed), and pass that array to WaitAll
. The threaded tasks will get one ManualResetEvent object each, and call the Set
method when they are ready. WaitAll
will block the calling thread until all tasks are done. I'll give a C# code example:
private void SpawnWorkers()
{
ManualResetEvent[] resetEvents = new[] {
new ManualResetEvent(false),
new ManualResetEvent(false)
};
// spawn the workers from a separate thread, so that
// the WaitAll call does not block the main thread
ThreadPool.QueueUserWorkItem((state) =>
{
ThreadPool.QueueUserWorkItem(Worker1, resetEvents[0]);
ThreadPool.QueueUserWorkItem(Worker2, resetEvents[1]);
WaitHandle.WaitAll(resetEvents);
this.BeginInvoke(new Action(AllTasksAreDone));
});
}
private void AllTasksAreDone()
{
// OK, all are done, act accordingly
}
private void Worker1(object state)
{
// do work, and then signal the waiting thread
((ManualResetEvent) state).Set();
}
private void Worker2(object state)
{
// do work, and then signal the waiting thread
((ManualResetEvent)state).Set();
}
Note that the AllTasksAreDone
method will execute on the thread pool thread that was used to spawn the workers, and not on the main thread... I assume that many other languages have similar constructs.