-1
我們的應用程序創建了許多在CLR線程池上運行的任務。 任務數量可能從10到10萬。加速CLR線程池增長
當任務數量快速增加時,許多任務在給定時間內無法完成。
這是因爲線程池每秒只添加一個新線程(儘管可能有數百個等待任務)。
下面的測試演示了此問題:
[Test]
public void TestTasks()
{
ThreadPool.SetMaxThreads(10000, 10000);
ThreadPool.SetMinThreads(1, 1);
var source = new CancellationTokenSource();
for (int i=0; i<1000; i++)
{
int ci = i;
Task.Run(() => {
Console.WriteLine(DateTime.Now.ToString("hh:mm:ss.fff") + $" {ci} - START");
Thread.Sleep(TimeSpan.FromSeconds(5)); // long operation simulatation
Console.WriteLine(DateTime.Now.ToString("hh:mm:ss.fff") + $" {ci} - FINISH");
}, source.Token);
}
Thread.Sleep(TimeSpan.FromSeconds(10));
source.Cancel();
}
的典型輸出是
01:38:37.171 0 - START
01:38:37.171 1 - START
01:38:37.172 2 - START
01:38:37.172 3 - START
01:38:38.029 4 - START
01:38:39.029 5 - START
01:38:40.030 6 - START
01:38:41.031 7 - START
01:38:42.029 8 - START
01:38:42.172 0 - FINISH
01:38:42.172 9 - START
01:38:42.173 3 - FINISH
01:38:42.173 1 - FINISH
01:38:42.173 2 - FINISH
01:38:42.173 10 - START
01:38:42.173 11 - START
01:38:42.173 12 - START
01:38:43.029 13 - START
01:38:43.030 4 - FINISH
01:38:43.030 14 - START
01:38:44.030 5 - FINISH
01:38:44.030 15 - START
01:38:44.030 16 - START
01:38:45.029 17 - START
01:38:45.031 6 - FINISH
有什麼辦法來增加線程池的增長速度?
更新1 上面的例子顯示的主要問題:任務是由它採用異步新的現代化圖書館創建/等待樣式代碼。但是大部分任務都是帶有線程阻塞操作的舊式遺留代碼。該應用程序工作。並且在恆定的低或恆定的高負載下它表現出良好的性能。性能問題在任務數量迅速增加時開始:儘管有數千個等待任務,但CPU利用率保持較低。
什麼是最容易的方法來應對所描述的情況?
不,它被固定在半秒。它只是作爲TP線程的對策,花費很長時間才能完成它們的工作,並不意味着創建線程爆炸。設置「太長」的措施,半秒鐘。對於現代處理器來說,這是一個簡單的〜40億cpu指令,除非你計算pi的值,你只能通過過多的I/O延遲來獲得它。通用解決方案是異步代碼,這種類型不需要TP線程來等待I/O操作完成。 –