2011-07-07 12 views
17

Perché parallel.ForEach termina con OperationCancelledException, mentre si utilizza GetConsumableEnumerable?Parallel.ForEach loop con BlockingCollection.GetConsumableEnumerable

//outside the function 
static BlockingCollection<double> _collection = new  BlockingCollection<double>(); 


    var t = Task.Factory.StartNew(Producer);    
    Parallel.ForEach(_collection.GetConsumingEnumerable(),item => Console.WriteLine("Processed {0}", item)); 
    Console.WriteLine("FINISHED processing"); 



public static void Producer() 
{ 
    var data = Enumerable.Range(1, 1000); 
    foreach (var i in data) 
    { 
     _collection.Add(i); 
     Console.WriteLine("Added {0}",i); 
    } 

    Console.WriteLine("Finished adding"); 
    _collection.CompleteAdding(); 
} 

risposta

17

Utilizzando Parallel.ForEach con BlockingCollection è un po 'problematico, come ho scoperto di recente. Può essere fatto funzionare, ma richiede un piccolo sforzo in più.

Stephen Toub ha uno excellent blog post on it e se si scarica il progetto "Parallel Extension Extras" (also available on NuGet), è disponibile un codice pronto per essere d'aiuto.

+0

Ciò che davvero mi irrita è il motivo per cui Parallel.ForEach genera un'eccezione quando chiamo _collection.CompleteAdding(). – Sam

+0

@Sam: non vorrei dire, ad essere onesti. C'è troppa magia profonda in corso lì per me avere una certa fiducia nel dire la cosa giusta :) –

+0

L'attuale URL per le estensioni parallele Extra: https://code.msdn.microsoft.com/ParExtSamples e qualcuno ha fatto un NuGet delle estensioni: https://www.nuget.org/packages/MSFT.ParallelExtensionsExtras/ – Reyhn

Problemi correlati