在這裡你可以學到Microsoft研究CLR實現線程池的原理機制,從而更靈活的處理CLR在實際代碼應中線程池的問題,下面我們來看看吧。
CLR教程之線程池的產生
當 CLR 初始化時,其線程池中不含有線程。當應用程序要創建線程來執行任務時,該應用程序應請求線程池線程來執行任務。線程池知道後將創建一個初始線程。該新線程經歷的初始化和其他線程一樣;但是任務完成後,該線程不會自行銷毀。相反,它會以掛起狀態返回線程池。如果應用程序再次向線程池發出請求,那麼這個掛起的線程將激活並執行任務,而不會創建新線程。這節約了很多開銷。只要線程池中應用程序任務的排隊速度低於一個線程處理每項任務的速度,那麼就可以反復重用同一線程,從而在應用程序生存期內節約大量開銷。
那麼,如果線程池中應用程序任務排隊的速度超過一個線程處理任務的速度,則線程池將創建額外的線程。當然,創建新線程確實會產生額外開銷,但應用程序在其生存期中很可能只請求幾個線程來處理交給它的所有任務。因此,總體來說,通過使用線程池可以提高應用程序的性能。線程池的一個絕妙特性是:它是啟發式的。如果您的應用程序需要執行很多任務,那麼線程池將創建更多的線程。如果您的應用程序的工作負載逐漸減少,那麼線程池線程將自行終止。線程池的算法確保它僅包含置於其上的工作負荷所需要的線程數!
因此,希望您現在已理解了線程池的基本概念,並明白了它所能提供的性能優勢。現在我將給出一些代碼來說明如何使用線程池。首先,您應該知道線程池可以提供四種功能:
◆異步調用方法
◆以一定的時間間隔調用方法
◆當單個內核對象得到信號通知時調用方法
◆當異步 I/O 請求結束時調用方法
前三種功能非常有用,我將在本專欄中加以說明。而應用程序開發人員很少使用第四種功能,因此在此我將不做說明;有可能在將來的專欄中講到。
功能 1:CLR線程池教程之異步調用方法
在您的應用程序中,如果有創建新線程來執行任務的代碼,那麼我建議您用命令線程池執行該任務的新代碼來替換它。事實上,您通常會發現,讓線程池執行任務比讓一個新的專用線程來執行任務更容易。要排隊線程池任務,您可以使用 System.Threading 命名空間中定義的 ThreadPool 類。ThreadPool 類只提供靜態方法,且不能構造它的實例。要讓線程池線程異步調用方法,您的代碼必須調用一個 ThreadPool 的重載 QueueUserWorkItem 方法,如下所示:
public static Boolean QueueUserWorkItem(WaitCallback wc, Object state); public static Boolean QueueUserWorkItem(WaitCallback wc); 這些方法將“工作項”(和可選狀態數據)排隊到線程池的線程中,並立即返回。工作項只是一種方法(由 wc 參數標識),它被調用並傳遞給單個參數,即狀態(狀態數據)。沒有狀態參數的 QueueUserWorkItem 版本將 null 傳遞給回調方法。最後,池中的某些線程將調用您的方法來處理該工作項。您編寫的回調方法必須與 System.Threading.WaitCallback 委托類型相匹配,其定義如下:
public delegate void WaitCallback(Object state);
代碼示例:
01
using
System;
02
using
System.Threading;
03
04
public
class
Test
05
{
06
// 存放要計算的數值的字段
07
static
double
number1 = -1;
08
static
double
number2 = -1;
09
10
public
static
void
Main()
11
{
12
// 獲取線程池的最大線程數和維護的最小空閒線程數
13
int
maxThreadNum, portThreadNum;
14
int
minThreadNum;
15
ThreadPool.GetMaxThreads(
out
maxThreadNum,
out
portThreadNum);
16
ThreadPool.GetMinThreads(
out
minThreadNum,
out
portThreadNum);
17
Console.WriteLine(
"最