2010-02-16 40 views
18

ParallelEnumerable有一個靜態成員AsParallel。如果我有IEnumerable<T>並且想要使用Parallel.ForEach這是否意味着我應該始終使用AsParallelParallel.ForEach是否需要AsParallel()

例如 這兩個都是正確的(一切都是平等的)?

沒有AsParallel

List<string> list = new List<string>(); 
Parallel.ForEach<string>(GetFileList().Where(file => reader.Match(file)), f => list.Add(f)); 

AsParallel

List<string> list = new List<string>(); 
Parallel.ForEach<string>(GetFileList().Where(file => reader.Match(file)).AsParallel(), f => list.Add(f)); 

回答

21

這取決於被調用的內容,它們是單獨的問題。

.AsParallel()並行化枚舉不是委託任務。

Parallel.ForEach並行化,將任務分配給工作線程的每個元素。

因此,除非您的源枚舉獲得平行(例如reader.Match(file)昂貴),否則它們是平等的。到你最後的問題,是的,兩者都是正確的。

此外,還有可能要看看那個縮短了一點,仍然得到PLINQ的最大利益另一個構造:

GetFileList().Where(file => reader.Match(file)).ForAll(f => list.Add(f)); 
+2

嗯...究竟是什麼parrallelizing枚舉?或者至少如何將這種平行化與任務授權分開? – dkackman 2010-02-16 02:04:31

+2

@dkackman'.AsParallel()'在這種情況下爲並行執行計數,特別是'.SelectMany()'的並行版本。考慮一個擁有大量'Where'子句但沒有順序的枚舉,我們可以在儘可能多的內核中同時評估where子句,從而將下一個列舉到下一個可用線程,使其速度幾乎快了n倍。我們對該結果的處理也可以用相同的方式進行處理,或者在一個線程中同步,或者在可用的核心上傳播,那麼'Parallel.ForEach'或'.ForAll'部分是否合理? – 2010-02-16 07:09:34

+0

這確實有道理。謝謝Nick。 – dkackman 2010-02-16 12:36:57