2010-01-11 59 views
26

是否有一個幻數或公式用於設置ThreadPool的SetMaxThreads和SetMinThreads的值?我有成千上萬的需要執行的長時間運行的方法,但是卻無法找到設置這些值的完美匹配。任何意見將不勝感激。ThreadPool SetMaxThreads和SetMinThreads Magic Number

回答

39

線程的默認最小數量是您的機器具有的核心數量。這是一個很好的數字,運行比核心更多的線程通常並不合適。

線程的默認最大數量是您在.NET 2.0 SP1及更高版本上具有的核心數量的250倍。這裏有大量的呼吸室。在四核機器上,如果沒有任何線程在合理的時間內完成,則需要499秒達到最大值。

線程池調度程序嘗試將活動線程的數目限制爲最小值,默認情況下爲您擁有的核心數。如果活動線程沒有完成,它允許一秒多線程啓動。運行了很長時間的線程或做了很多非I/O引起的阻塞並不適合線程池。您應該使用常規線程來代替。

達到最大值並不健康。在四核心機器上,這些線程的堆棧將消耗千兆字節的虛擬內存空間。獲得OOM很可能。如果這是您的問題,請考慮降低最大線程數。或者考慮從幾個線程安全隊列中接收幾個接收工作包的常規線程。

+0

請看看[我的相關問題](http://stackoverflow.com/q/7974559/75500「運行一批進程並報告每個進程的進度「),一位用戶在那裏建議我應該使用[ThreadPool],根據你的說法,我認爲這不是一個好主意,也許你可以幫助我。 – Shimmy 2011-11-03 01:39:25

+3

@Hans Passant:這幾乎是正確的,首先t他默認的最大線程數取決於應用程序使用的.NET Framework版本(例如, 2.0每個核心25個)。第二件事是,增加線程的最小數量會導致線程無延遲地啓動,直到達到最小數量(如果不需要,它們不會啓動)。如果達到最小延遲時間,新線程將只在延遲時間內創建,導致長時間運行(> 500毫秒)時性能提高,但在短時間運行時性能下降。 – haze4real 2012-11-09 00:14:10

+0

@HansPassant - 如果創建可能被阻塞等待外部IO的線程,我認爲有些情況下「最佳」最小值確實會高於核心數量。因爲「阻塞」線程仍然「計數」到最低限度,對吧? (我知道這不會超過幾秒鐘,因爲在此之後,調度器將創建這些額外的線程,只要確保我理解了推理。) – ToolmakerSteve 2018-03-04 18:18:38

6

通常情況下,幻數是讓它獨自一人。 ThreadPool在處理這個方面做得很好。這就是說,如果你正在做很多長時間運行的服務,那麼這些服務將有很長的等待時間,你可能想要增加最大的線程來處理更多的選項。 (如果進程沒有被阻塞,如果你增加線程數,你可能會放慢速度...)

配置文件以查找正確的編號。

+0

如果我要更改最大線程(和最小線程?),則有兩個參數,工作線程和完成端口線程。什麼是完成端口線程計數? – Benny 2010-01-11 18:42:49

+0

另外,如果我單獨離開ThreadPool,而不設置最小/最大線程,則會遇到OutOfMemoryException,並且所有線程都會失敗。 – Benny 2010-01-11 18:44:55

+3

這是一個不同的問題 - 你可以通過限制它來減少工作量,但是內存耗盡與線程無關...... – 2010-01-11 20:14:05

5

如果您想要更好的控制,您可能需要考慮不使用內置的ThreadPool。在http://www.codeproject.com/KB/threads/smartthreadpool.aspx有一個很好的替代品。

+0

我試圖使用SmartThreadPool,但無濟於事。在排隊所有工作項後,我嘗試使用WaitForIdle(我有執行後邏輯來運行),它從不阻止,只是向右移動。可能是在鍵盤和電腦之間,但還沒有想出那一個呢 – Benny 2010-01-11 18:41:43