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.
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); }
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.