Using the Thread Pool to Process Many Items at Once

6 07 2011

A common requirement of concurrent programming is the ability to wait until a work item or set of work items that were queued to the thread pool have completed. A simple example for a single work item is to allocate an event that is set at the end of the work and have the calling thread wait on it.

using(ManualResetEvent finishedWork = new ManualResetEvent(false))
{
    ThreadPool.QueueUserWorkItem(delegate
    {
        //do the work on a Thread Pool thread
        finishedWork.Set();
    });

    //do some work at the same time as the Thread Pool
    //wait for the work to be finished
    finishedWork.WaitOne();
}

One approach for many work items would be to create multiple events and wait for them all to be set. The more efficient approach is to avoid creating more than one event and have the last thread to complete signal the calling thread that all the work has been finished.

int numWorkers = 10;
using(ManualResetEvent finishedWork = new ManualResetEvent(false))
{
    for (int i = 0; i < numWorkers; ++i)
    {
        ThreadPool.QueueUserWorkItem(delegate
        {
            //do the work on a Thread Pool thread

            if(Interlocked.Decrement(ref numWorkers) == 0)
                finishedWork.Set();
        });
    }

    //do some work at the same time as the Thread Pool
    //wait for the work to be finished
    finishedWork.WaitOne();
}
Advertisements