1. Introduction
Recently, I have been studying the concept of thread pool in C # multi-thread programming. I did not understand, so I searched for it on msdn and csdn and finally figured it out. "why", I wrote this article after installing my understanding and modification, hoping to help later users.
2. Concept of Thread Pool
You can use a thread pool to more effectively utilize multiple threads based on application needs. Many applications use multiple threads, but these threads often spend a lot of time waiting for the event to occur in the sleep state. It is also troublesome for programmers to manually manage multiple threads. In fact, using the thread pool is to provide an auxiliary thread pool managed by the system for the application, so that you can focus on application tasks rather than thread management.
In fact, to execute short tasks that require multiple threads, The threadpool class is the most convenient and best method to use multiple threads. The thread pool can optimize the execution process of these tasks to increase the throughput. It not only enables the system to optimize the execution process for this process, it also enables the system to optimize the execution process for other processes on the computer, even if your application knows nothing about these processes. The thread pool enables the system to optimize the thread time slice after considering all the current processes on the computer.
. NET Framework uses the thread pool for the following purposes: asynchronous call, system. Net socket connection, asynchronous I/O completion, and waiting for timer and registration.
Each process has only one threadpool object. The thread pool is created when you call threadpool. queueuserworkitem for the first time, or when a timer or registered wait operation queues a callback method. One thread monitors all tasks that have been queued into the thread pool. After a task is completed, the thread in the thread pool executes the corresponding callback method. You cannot cancel a work item after it is queued.
Call system. Threading. threadpool. queueuserworkitem (waitcallback) to use the thread pool. waitcallback is the method to be added to the queue. You can also use system. Threading. threadpool. registerwaitforsingleobject () and pass waithandle to queue work items related to the waiting operation to the thread pool. In both cases, the thread pool uses or creates a background thread to call the callback method.
In the following cases, it is suitable for creating and managing your own threads instead of using threadpool:
1) if you need to give a task a specific priority.
2) If you have tasks that may run for a long time (and thus block other tasks.
3) if you need to place threads in a single thread unit (all threadpool threads are in a multi-thread unit ).
4) if you need a permanent identifier associated with the thread. For example, you may want to use a dedicated thread to abort the thread, suspend it, or discover it by name.
3. Sample Code
C #
// Copyright (c) Microsoft Corporation. All rights reserved.
// This example uses multiple threads to calculate the Fibonacci series (an integer series where each number equals the sum of the first two ).
Using system;
Using system. Threading;
// The maid class provides an interface for using an auxiliary
// Thread to perform the lengthy maid (n) calculation.
// N is provided to the Fibonacci constructor, along with
// Event that the object signals when the operation is complete.
// The result can be retrieved with the fibofn property.
Public class Fibonacci
...{
Public Fibonacci (int n, manualresetevent doneevent)
...{
_ N = N;
_ Doneevent = doneevent;
}
// Wrapper method for use with thread pool.
Public void threadpoolcallback (Object threadcontext)
...{
Int threadindex = (INT) threadcontext;
Console. writeline ("thread {0} started...", threadindex );
_ Fibofn = calculate (_ n );
Console. writeline ("thread {0} result calculated...", threadindex );
_ Doneevent. Set ();
}
// Recursive method that calculates the nth Maid number.
Public int calculate (int n)
...{
If (n <= 1)
...{
Return N;
}
Else
...{
Return calculate (n-1) + calculate (n-2 );
}
}
Public int n... {Get... {return _ n ;}}
Private int _ N;
Public int fibofn... {Get... {return _ fibofn ;}}
Private int _ fibofn;
Manualresetevent _ doneevent;
}
Public class threadpoolexample
...{
Static void main ()
...{
Const int maid = 10;
// One event is used for each Fibonacci object
Manualresetevent [] doneevents = new manualresetevent [Maid];
Maid [] maid = new maid [Maid];
Random r = new random ();
// Configure and launch threads using threadpool: puts 10 threads into the thread pool in order
// The queueuserworkitem method has two versions. For details, see msdn:
// Threadpool. queueuserworkitem (waitcallback)
// Threadpool. queueuserworkitem (waitcallback, object)
// I is the data object (that is, the parameter) used for the callback method, that is, I is passed to the threadpoolcallback () function as the parameter.
Console. writeline ("Launching {0} tasks...", FIG );
For (INT I = 0; I <maid; I ++)
...{
Doneevents [I] = new manualresetevent (false );
Maid F = new maid (R. Next (20, 40), doneevents [I]);
Fiber Array [I] = F;
Threadpool. queueuserworkitem (F. threadpoolcallback, I );
}
// Wait for all threads in pool to calculation...
Waithandle. waitall (doneevents );
Console. writeline ("Calculations complete .");
// Display the results...
For (INT I = 0; I <maid; I ++)
...{
Fibonacci F = fiber array [I];
Console. writeline ("Maid ({0}) = {1}", F. N, F. fibofn );
}
}
}