Recipe 15.10 Waiting for All Threads in theThread Pool to Finish
Problem
For threads that are
manually created via the Thread class, you can
call the Join method to wait for a thread to
finish. This works well when you need to wait for all threads to
finish processing before an application terminates. Unfortunately,
the thread pool threads do not have a Join method.
You need to make sure that all threads in the thread pool have
finished processing before another thread terminates or your
application's main thread terminates.
Solution
Use a combination of the
ThreadPool
methods—GetMaxThreads and
GetAvailableThreads—to determine when the
ThreadPool is finished processing the requests:
public static void Main( )
{
for(int i=0;i<25;i++)
{
// have to wait or threadpool never gives out threads to requests
Thread.Sleep(50);
// queue thread request
ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc),i);
}
// have to wait here or the background threads in the thread
// pool would not run before the main thread exits.
Console.WriteLine("Main Thread waiting to complete...");
bool working = true;
int workerThreads = 0;
int completionPortThreads = 0;
int maxWorkerThreads = 0;
int maxCompletionPortThreads = 0;
// get max threads in the pool
ThreadPool.GetMaxThreads(out maxWorkerThreads,out maxCompletionPortThreads);
while(working)
{
// get available threads
ThreadPool.GetAvailableThreads(out workerThreads,out completionPortThreads);
if(workerThreads == maxWorkerThreads)
{
// allow to quit
working = false;
}
else
{
// sleep before checking again
Thread.Sleep(500);
}
}
Console.WriteLine("Main Thread completing...");
}
Static void ThreadProc(Object stateInfo)
{
//show we did something with this thread...
Console.WriteLine("Thread {0} running...", stateInfo);
Thread.Sleep(1000);
}
Discussion
This approach is a bit coarse; since the CLR does not allow access to
the thread objects being created, the best we can do is to see when
the ThreadPool no longer has requests queued. If this approach is not
sufficient for your needs, you could implement your own thread pool,
but be careful of the many pitfalls that await you because thread
pools are not easy to get right in all cases. Some of the issues are
having too many or too few threads to service requests, determining
initial levels of threads in the pool, and deadlocking threads.
See Also
See the "ThreadPool Class" topic in
the MSDN documentation. Also see Applied Microsoft .NET
Framework Programming by Jeffrey Richter (Wintellect).
|