Recipe18.7.Determining Whether a Request for a Pooled Thread Will Be Queued


Recipe 18.7. Determining Whether a Request for a Pooled Thread Will Be Queued

Problem

Your application will be creating many threads from the thread pool. When creating a thread from this pool, you want to be informed as to whether a thread in the pool is available or if the request for a new thread will have to be queued. Basically, you want to know whether a thread is available for immediate use from the thread pool.

Solution

Use the ThreadPool.GetAvailableThreads method to get the number of worker threads currently available in the ThreadPool. This allows you to determine whether you should queue another request to launch a thread via ThreadPool.QueueUserWorkItem or should take an alternate action.

The Main method shown here calls a method (SpawnManyThreads) to spawn lots of threads from the ThreadPool, then waits for a bit to simulate processing:

 public class TestThreads {     public static void Run()     {         SpawnManyThreads();         // 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…");         Thread.Sleep(2000);         Console.WriteLine("Main Thread completing…");     } 

The SpawnManyThreads method launches threads and pauses between each launch to allow the ThreadPool to register the request and act upon it. The isThreadAvailable method is called with the parameter set to true to determine whether there is a worker thread available for use in the THReadPool:

 public static bool SpawnManyThreads() {     try     {         for(int i=0;i<500;i++)         {             // Have to wait or thread pool never gives out threads to             // requests.             Thread.Sleep(100);             // Check to see if worker threads are available in the pool.             if(true == IsThreadAvailable(true))             {                 // Launch thread if queue isn't full.                 Console.WriteLine("Worker Thread was available…");                 ThreadPool.QueueUserWorkItem(ThreadProc,i);             }             else                 Console.WriteLine("Worker Thread was NOT available…");         }     }     catch(Exception e)     {     Console.WriteLine(e.ToString());     return false; } return true; } 

The IsThreadAvailable method calls ThreadPool.GetAvailableThreads to determine whether the ThreadPool has any available worker threads left. If you pass false as the checkWorkerThreads parameter, it also sees whether there are any completion port threads available. The GetAvailableThreads method compares the current number of threads allocated from the pool against the maximum ThreadPool tHReads. The worker thread maximum is 25 per CPU, regardless of the number of CPUs, in v1.1 of the CLR. In v2.0 of the CLR, the maximum number of worker threads is actually settable. The maximum number of worker threads applies to each CPU, so if it is set to 25 on a two-processor machine, the maximum will actually be 50.

 public static bool IsThreadAvailable(bool checkWorkerThreads) {     int workerThreads = 0;     int completionPortThreads = 0;     // Get available threads.     ThreadPool.GetAvailableThreads(out workerThreads,         out completionPortThreads);     // Indicate how many work threads are available.     Console.WriteLine("{0} worker threads available in thread pool.",         workerThreads);     if(checkWorkerThreads)     {         if(workerThreads > 0)             return true;     }     else // Check completion port threads.     {         if(completionPortThreads > 0)             return true;     }     return false; } 

This is a simple method to call in a threaded fashion:

     static void ThreadProc(Object stateInfo)     {         // Show we did something with this thread.         Console.WriteLine("Thread {0} running…",stateInfo);         Thread.Sleep(1000);     } } 

Discussion

The THReadPool is a great way to perform background tasks without having to manage all aspects of the thread yourself. It can be handy to know when the ThreadPool itself is going to become a bottleneck to your application, and the GetAvailableThreads method can help you. However, you might want to check your application design if you are consistently using this many threads, as you might be losing performance due to contention or context switching. Queuing up work when the ThreadPool is full simply queues it up for execution once one of the threads comes free; the request isn't lost, just postponed.

See Also

See the "ThreadPool Class" topic in the MSDN documentation; see Applied Microsoft.NET Framework Programming (Wintellect).



C# Cookbook
Secure Programming Cookbook for C and C++: Recipes for Cryptography, Authentication, Input Validation & More
ISBN: 0596003943
EAN: 2147483647
Year: 2004
Pages: 424

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net