Using ThreadPools


As the name of the class suggests, System::Threading::ThreadPool provides a system-managed pool of threads on which to run your application's threads. Being managed by the system, your multithreaded application loses control of how threads are created, managed, and cleaned up. But, in many cases, your application has no real need to manage threads, as aborting, joining, interrupting, suspending, and resuming a thread in an application is not always needed.

What you lose in control you get back in ease of use. Plus, it simplifies multithreaded programming, especially if your application is made up of numerous threads. With thread pooling, you're able to focus on developing your business logic without getting bogged down with thread management.

For those of you who are interested, this is, at a high level, how a thread pool works. Basically, a thread pool is created the first time ThreadPool is called. Thread pools use a queuing system that places a work item (a thread request) on an available thread pool thread. If no thread pool thread is available, then a new one is created up to a default maximum of 25 threads per available processor. (You can change this maximum using CorSetMaxThreads, defined in the mscoree.h file.) If the maximum number of threads is reached, then the work item remains on a queue until a thread pool thread becomes available. There is no limit to the number of work items that can be queued. (Well, that's not quite true. You are restricted to available memory.)

Each thread pool thread runs at the default priority and can't be cancelled.

Note

Thread pool threads are background threads. As such, you need the main program thread or some other foreground thread to remain alive the entire life of the application.

You add a work item to the thread pool queue by calling the ThreadPool class's static QueueUserWorkItem() method. The QueueUserWorkItem() method takes a WaitCallback delegate as a parameter and an object pointer parameter to allow you to pass information to the generated thread. (The method is overloaded so that you don't have to pass an Object parameter if none is required.) The WaitCallback delegate has the following signature:

 public __gc __delegate void WaitCallback(Object* state); 

The Object* state parameter will contain the Object pointer that was passed as the second parameter to the QueueUserWorkItem() method. The QueueUserWorkItem() method returns true if the method successfully queues the work item; otherwise, it returns false.

The example in Listing 16-6 shows how simple it is to create two ThreadPool threads.

Listing 16-6: Using Thread Pools

start example
 using namespace System; using namespace System::Threading; __gc class MyThread { public:     void ThreadFunc(Object* stateInfo)     {         for (Int32 i = 0; i < 10; i++)         {             Console::WriteLine(S"{0} {1}", stateInfo, i.ToString());             Thread::Sleep(100);         }     } }; Int32 main() {     Console::WriteLine(S"Main Program Starts");     MyThread *myThr1 = new MyThread();     ThreadPool::QueueUserWorkItem(         new WaitCallback(myThr1, &MyThread::ThreadFunc), S"Thread1");     ThreadPool::QueueUserWorkItem(         new WaitCallback(myThr1, &MyThread::ThreadFunc), S"Thread2");     Thread::Sleep(2000);     Console::WriteLine(S"Main Program Ends");     return 0; } 
end example

There are only a couple of things of note in the preceding example. The first is the second parameter in the call to the QueueUserWorkItem() method. This parameter is actually extremely flexible, as you can pass it any managed data type supported by the .NET Framework. In the preceding example, I passed a String, but you could pass it an instance to an extremely large and complex class if you want.

The second thing of note is the Sleep() method used to keep the main thread alive. Once the main thread dies, so do all the threads in the ThreadPool, no matter what they are doing.

You can see the results of ThreadPooling.exe in Figure 16-7.

click to expand
Figure 16-7: The ThreadPooling program in action




Managed C++ and. NET Development
Managed C++ and .NET Development: Visual Studio .NET 2003 Edition
ISBN: 1590590333
EAN: 2147483647
Year: 2005
Pages: 169

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