2017-01-12 47 views
1

我有以下代碼:懶惰評價並行查詢

static IEnumerable<int> foo() 
{ 
    int den = 0; 
    yield return 10; 
    yield return 10; 
    yield return 10; 
    yield return 10/den; 
    yield return 10/den; 
} 
static public void Main() 
{ 
    foreach (var item in foo().AsParallel().Take(3)) 
    { 
     Console.WriteLine(item); 
    } 
    Console.ReadLine(); 
} 

此代碼失敗(因爲採集的實際未使用的元素將被計算 - 計算PLINQ數據塊)。 .Net是否支持真正的「懶惰」並行(沒有使用未使用元素的塊的預計算)?

注意:這只是一個簡單的例子。據我所知,AsParallel應該用於大數據以避免開銷。

+3

我錯過了什麼嗎?你只需要改變順序吧? 'foo()。拿(3).AsParallel()' – wdosanjos

+0

有什麼區別? – LmTinyToon

+3

'AsParallel()'不知道後面會發生什麼,所以它並行化了集合中的所有項目,從而導致了錯誤。 '採取(3).AsParallel()'採取前3個元素然後並行化他們,因此沒有錯誤。 – wdosanjos

回答

1

如果你禁止塊的預計算,那麼你不能並行做任何工作。只有並行化任何流式運算符的方法是讓它們查詢數據源的更多項目,而不是確定它們需要並預先計算它們的值。如果你不能允許任何預先計算數據,那麼按照定義,你不能對任何這些運算符進行任何並行處理,而只需要使用常規的LINQ操作而不是PLINQ。

+0

但是爲什麼plinq會處理額外的未使用的元素?爲什麼要預先計算額外的元素?我無法理解這個想法。我不明白爲什麼存儲計算的塊將以更好的性能並行發揮作用。 – LmTinyToon

+0

@LmTinyToon如果您只處理已詢問的物品,那麼*按照定義*您一次只處理一件物品,因爲一次只需要處理一件物品。要處理多件物品的唯一可能方式是要求獲得比尚未向您詢問的物品更多的物品。 – Servy