Parallel.ForEach () vs. foreach (IEnumerable .AsParallel ())

Erg, sto cercando di trovare questi due metodi nel BCL usando Reflector, ma non li posso localizzare. Qual è la differenza tra questi due frammenti?

UN:

IEnumerable items = ... Parallel.ForEach(items, item => { ... }); 

B:

 IEnumerable items = ... foreach (var item in items.AsParallel()) { ... } 

Ci sono diverse conseguenze nell’usare l’una sull’altra? (Supponiamo che qualunque cosa stia facendo nei corpi tra parentesi di entrambi gli esempi sia infallibile).

Fanno qualcosa di completamente diverso.

Il primo accetta il delegato anonimo e esegue più thread su questo codice in parallelo per tutti i diversi elementi.

Il secondo non è molto utile in questo scenario. In breve, è inteso a fare una query su più thread e combinare il risultato e restituirlo al thread chiamante. Quindi il codice sull’istruzione foreach rimane sempre sul thread dell’interfaccia utente.

Ha senso solo se fai qualcosa di costoso nella query linq alla destra della chiamata AsParallel() , come:

  var fibonacciNumbers = numbers.AsParallel().Select(n => ComputeFibonacci(n)); 

La differenza è che B non è parallelo. L’unica cosa che AsParallel() fa è che AsParallel() un object IEnumerable , in modo che quando si usano i metodi LINQ, vengano utilizzate le loro varianti parallele. Il GetEnumerator() del wrapper (che viene utilizzato dietro le quinte nel foreach ) restituisce anche il risultato del GetEnumerator() della raccolta originale GetEnumerator() .

A proposito, se si desidera esaminare i metodi in Reflector, AsParallel() trova nella class System.Linq.ParallelEnumerable nell’assembly System.Core . Parallel.ForEach() è nell’assembly mscorlib (spazio dei nomi System.Threading.Tasks ).

Il secondo metodo non sarà parallelo al modo corretto di utilizzare AsParallel () nel tuo esempio

 IEnumerable items = ... items.AsParallel().ForAll(item => { //Do parallel stuff here });