The Will Will Web

記載著 Will 在網路世界的學習心得與技術分享

使用 ThreadPool 時應注意預設同時執行的 Thread 數量

之前我們有個專案需要透過 Console Application (指令列程式) 解析上萬個檔案,而且每解析一個檔案就必須要啟動這個程式一次,為了縮短程式執行的時間,我們當時就採用 ThreadPool 技術進行開發,結果最近客戶購買了新主機,安裝了我們的程式後卻發現經常還沒跑完就死了,研究了好一番功夫才發現問題出在 .NET 2.0 預設的 Thread 數量變了。

我們當時使用了 ThreadPool 且並沒有透過 ThreadPool.SetMaxThreads 設定同時執行的 Threads 上限,當時的電腦是單 CPU + 單核心,因此程式執行的相安無事。

查詢資料得知,在 .NET 2.0 SP1 之前,每個 CPU 或每個核心(Core)預設 ThreadPool 的同時執行緒上限是 25 個 Threads,但在 .NET 2.0 SP1 以後卻調整到 250 個 Threads,這是個很大的差別,以致於我們一個程式中同時開啟太多個 Console Application,超出了系統可接受的上限,所以許多程式都沒有執行完就自動結束了,況且客戶的新電腦是雙 CPU + 四核心,你可想見程式不出問題也難!

最後,我們利用 ThreadPool.SetMaxThreads 這個靜態方法設定同時執行的 Threads 上限,這個問題就迎刃而解:

// 設定最大同時執行的 Thread 數量
ThreadPool.SetMaxThreads(10, 10);

---

另外提及一點,在 MSDN 上的 ThreadPool 的說明文件,繁體中文版英文版 的內容是不一致的:

英文版的 ThreadPool Class 中提及同時執行 Threads 上限的說明文字如下:

There is one thread pool per process. The thread pool has a default size of 250 worker threads per available processor, and 1000 I/O completion threads. The number of threads in the thread pool can be changed by using the SetMaxThreads method. Each thread uses the default stack size and runs at the default priority.

中文版的 ThreadPool 類別 中提及同時執行 Threads 上限的說明文字如下:

每一個處理序都會有一個執行緒集區。執行緒集區的預設大小為每個可用處理器 25 個背景工作執行緒,以及 1000 個 I/O 完成執行緒。您可以使用 SetMaxThreads 方法變更執行緒集區中的執行緒數目。每個執行緒都使用預設的堆疊大小,並且按照預設的優先權來執行。

我個人是覺得可能是因為翻譯的關係,當英文版文件修訂的時候其他國家翻譯文件不見得能夠立即更新,如果單單查閱中文版的 MSDN 文件也是有可能會吸收到錯誤的資訊。

相關連結