In multi-threaded programs, there are often two situations:
In an application, a thread spends most of its time waiting for an event to respond.
This is generally solved using ThreadPool;
Another situation: the thread is usually in sleep state, but is periodically awakened.
Timer (Timer) is generally used to solve this problem;
The ThreadPool class provides a thread pool maintained by the system (which can be considered as a thread container). This container must be supported by Windows 2000 and later systems, some of these methods call APIs that are only available in later versions of Windows.
To place a thread in a thread pool, use the ThreadPool. QueueUserWorkItem () method. The prototype of this method is as follows:
// Put a thread into the thread pool. The Start () method of the thread calls the Function Represented by the WaitCallback proxy object.
Public static bool QueueUserWorkItem (WaitCallback );
// The reload method is as follows. The parameter object is passed to the method represented by WaitCallback.
Public static bool QueueUserWorkItem (WaitCallback, object );
The ThreadPool class is a static class and you cannot or do not need to generate its objects. Once a project is added to the thread pool using this method, the project cannot be canceled.
Here, you don't need to create a thread on your own. You just need to write the work you want to do as a function and pass it to ThreadPool as a parameter. the QueueUserWorkItem () method is used. The passed method relies on the WaitCallback proxy object, and the thread creation, management, and running tasks are automatically completed by the system, you don't have to worry about complicated details.
ThreadPool usage:
First, the program creates a ManualResetEvent object, which is like a signal lamp and can be used to notify other threads.
In this example, when all the threads in the thread pool are finished, the ManualResetEvent object will be set as a signal to notify the main thread to continue running.
The ManualResetEvent object has several important methods:
When initializing this object, you can specify its default status (with signal/without signal );
After initialization, the object remains unchanged until its Reset () or Set () method is called:
Reset () method: Set it to non-signal state;
Set () method: Set it to a signal state.
WaitOne () method: suspends the current thread until the ManualResetEvent object is in a signal state and the thread is activated. The program then adds work items to the thread pool. The work items provided in the form of functions are used by the system to initialize automatically created threads. ManualResetEvent. the Set () method is called because ManualResetEvent is called. the main thread waiting for the WaitOne () method will receive this signal, so it will continue to execute and complete the subsequent work.
Example of ThreadPool usage:
Using System;
Using System. Collections;
Using System. Threading;
Namespace ThreadExample
{
// This is the data structure used to save information and will be passed as a parameter
Public class SomeState
{
Public int Cookie;
Public SomeState (int iCookie)
{
Cookie = iCookie;
}
}
Public class Alpha
{
Public Hashtable HashCount;
Public ManualResetEvent eventX;
Public static int iCount = 0;
Public static int iMaxCount = 0;
Public Alpha (int MaxCount)
{
HashCount = new Hashtable (MaxCount );
IMaxCount = MaxCount;
}
// The thread in the thread pool will call the Beta () method.
Public void Beta (Object state)
{
// Output the hash code value and Cookie value of the current thread
Console. WriteLine ("{0} {1}:", Thread. CurrentThread. GetHashCode (), (SomeState) state). Cookie );
Console. writeLine ("HashCount. count = {0}, Thread. currentThread. getHashCode () = {1} ", HashCount. count, Thread. currentThread. getHashCode ());
Lock (HashCount)
{
// If the current Hash table does not have the Hash value of the current thread, add
If (! HashCount. ContainsKey (Thread. CurrentThread. GetHashCode ()))
HashCount. Add (Thread. CurrentThread. GetHashCode (), 0 );
HashCount [Thread. CurrentThread. GetHashCode ()] =
(Int) HashCount [Thread. CurrentThread. GetHashCode ()]) + 1;
}
Int iX = 2000;
Thread. Sleep (iX );
// Interlocked. Increment () is an atomic operation. For details, refer to the following description.
Interlocked. Increment (ref iCount );
If (iCount = iMaxCount)
{
Console. WriteLine ();
Console. WriteLine ("Setting eventX ");
EventX. Set ();
}
}
}
Public class SimplePool
{
Public static int Main (string [] args)
{
Console. WriteLine ("Thread Pool Sample :");
Bool W2K = false;
Int MaxCount = 10; // allows a maximum of 10 threads to run in the thread pool
// Create a ManualResetEvent object and initialize it to a stateless state.
ManualResetEvent eventX = new ManualResetEvent (false );
Console. WriteLine ("Queuing {0} items to Thread Pool", MaxCount );
Alpha oAlpha = new Alpha (MaxCount );
// Create a work item
// Initialize the eventX attribute of the oAlpha object
OAlpha. eventX = eventX;
Console. WriteLine ("Queue to Thread Pool 0 ");
Try
{
// Load the work item into the thread pool
// Only APIs of Windows 2000 or later are used here, so the NotSupportException exception may occur.
ThreadPool. QueueUserWorkItem (new WaitCallback (oAlpha. Beta), new SomeState (0 ));
W2K = true;
}
Catch (NotSupportedException)
{
Console. WriteLine ("These APIs may fail when called on a non-Windows 2000 system .")