我想了解Parralel.For
和ThreadPool.QueueUserWorkItem
之間的差異。ThreadPool.QueueUserWorkItem vs Parallel.For
硬件&軟件:
- 英特爾酷睿i5(四核)
- Windows 7的64位教授
- DOTNET的4.5
案例1級的代碼:線程池
for (int index = 0; index < 5; index++)
{
ThreadPool.QueueUserWorkItem((indexParam) =>
{
int threadID = Thread.CurrentThread.ManagedThreadId;
Thread.Sleep(1000);
BeginInvoke((Action)delegate { listBox1.Items.Add("Completed " + indexParam.ToString() + " using thread " + threadID.ToString() + " (" + DateTime.Now.Second.ToString() + "." + DateTime.Now.Millisecond.ToString("000") + ")"); });
}, index);
}
輸出:
使用螺紋10(45.871)
使用螺紋11(45.875)已完成1
使用螺紋12(45.875)完成2
使用螺紋13已完成3(45.875)完成0
使用螺紋10(46.869)
案例完成4 2代碼:的Parallel.For
ParallelLoopResult result = Parallel.For(0, 5, (int index, ParallelLoopState loopState) =>
{
int threadID = Thread.CurrentThread.ManagedThreadId;
Thread.Sleep(1000);
BeginInvoke((Action)delegate { listBox1.Items.Add("Completed " + index.ToString() + " using thread " + threadID.ToString() + " (" + DateTime.Now.Second.ToString() + "." + DateTime.Now.Millisecond.ToString("000") + ")"); });
});
輸出:
使用螺紋10(16.923)
使用螺紋11(16.925)已完成1
使用螺紋12(16.925)完成2
使用螺紋13已完成3完成0 (16.926)
已完成4使用線程14(16.926)
問題:
從案例1的結果看來,只有四個線程處於活動狀態,然後第一個空閒線程才用於完成最終任務。在情況2中,看起來五個線程立即專用並且「同時」執行。
爲什麼QueueUserWorkItem的線程處理不使用第五個線程,比如並行類?
(ThreadPool.GetAvailableThreads(...)
確認1023個工作線程可用)。
道歉 - 輸出2的結果中存在拼寫錯誤。我更新了它 - 真正使用了第五個線程。 – Fortmann
毫無疑問,線程可以在幾毫秒內啓動(在ThreadPool的情況下,現有線程可以更快地分派)。爲什麼線程池決定不派遣第五個線程後,我已經明確要求它爲第五個任務做到這一點?前四個和最後一個線程之間的延遲恰好是一秒,這表明延遲不是由線程管理員造成的,管理員正在等待前四個中的一個完成。 – Fortmann
創建線程可能是一項昂貴的任務。如果您要求它運行1000個任務會怎麼樣?它不會啓動1000個線程,但它會緩慢增加,直到達到平衡。我懷疑如果你將睡眠時間增加到5秒作爲測試,你會看到線程池中的算法決定啓動一個新的線程。我個人使用一個線程池來處理負載變化很大的服務。游泳池將有40個線程活動到200個任意位置。在短期內,任務可能需要更長時間,但平均而言,游泳池在找到最佳性能點方面做得很好。 – AFrieze