2012-02-20 62 views
3

我在要處理的List中有一百萬個元素。
粗暴地將它們丟到一個Parallel.ForEach只會使CPU飽和。
相反,我將Elements Master Lists拆分爲幾塊,並將子列表放入並行循環中。按順序分割Parallel.Foreach循環上的負載

List<Element> MasterList = new List<Element>(); 
Populate(MasterList); // puts a Million elements into list; 

//Split Master List into 100 Lists of 10.0000 elements each 
List<List<Element>> ListOfSubLists = Split(MasterList,100); 

foreach (List<Element> EL in ListOfSubLists) 
{ 
    Parallel.ForEach(EL, E => 
    { 
    // Do Stuff 
    } 

    //wait for all parallel iterations to end before continuing 
}  

什麼是等待所有的並行迭代繼續上循環的下一次迭代之前結束的最好方法?

編輯:
如所陳述一些答案,「飽和CPU」是不準確的表達。
其實我只是想限制CPU使用率,並避免來自該處理的過度負載。

回答

4

Parallel.ForEach不會使CPU飽和;它使用了一些智力來決定多少個並行線程同時運行,用的最多63

參見:Does Parallel.ForEach limits the number of active threads?

您還可以設置最大並行度,如果你想,通過提供ParallelOptionsnew ParallelOptions { MaxDegreeOfParallelism = 5 }作爲Parallel.ForEach的第二個參數。

作爲最後一點,Parallel.ForEach阻塞,直到所有的迭代完成。所以你的代碼,正如所寫,起作用。您不需要等待迭代完成。其中

+2

我同意。枚舉10,000個項目的Parallel.foreach不會創建比一百萬更多/更少的線程。如果RAM成爲處理你的一百萬件物品的問題,那麼考慮BlockingCollection - 這將限制你在任何時候在內存中的物品數量。 – Ragoczy 2012-02-20 14:25:37

+0

謝謝。截至最後一句話,我不知道Parallel.ForEach被阻止。非常好知道。對於CPU飽和度,請參閱編輯。 – 2012-02-20 14:30:38

+0

@MikaJacobi如果你因爲某種原因想要非阻塞,你必須通過產生新的'Task'來自己做。 – 2012-02-20 14:38:43

2

你是什麼意思與ParallelOptions 一個屬性提供它「飽和CPU」

您仍然可以節流並行foreach循環是MaxDegreesOfParallelism

,讓你回去你的單一集合,例如

Parallel.ForEach(
    collection, 
    new ParallelOptions { MaxDegreeOfParallelism = 5}, 
    E => { DoStuff(E) } 
); 
+0

謝謝,非常有用的知道。我沒有意識到這一點。請參閱編輯。 – 2012-02-20 14:31:57