Parallel.ForEach () vs. foreach (IEnumerable <T> .AsParallel ())


143

Erg, saya mencoba menemukan dua metode ini di BCL menggunakan Reflector, tetapi tidak dapat menemukannya. Apa perbedaan antara kedua cuplikan ini?

SEBUAH:

IEnumerable<string> items = ...

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

B:

IEnumerable<string> items = ...

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

Apakah ada konsekuensi yang berbeda dari penggunaan satu di atas yang lain? (Asumsikan bahwa apa pun yang saya lakukan di badan kurung dari kedua contoh adalah thread aman.)

Jawaban:


148

Mereka melakukan sesuatu yang sangat berbeda.

Yang pertama mengambil delegasi anonim, dan menjalankan beberapa utas pada kode ini secara paralel untuk semua item yang berbeda.

Yang kedua tidak terlalu berguna dalam skenario ini. Singkatnya, ini dimaksudkan untuk melakukan kueri pada beberapa utas, dan menggabungkan hasilnya, dan memberikannya kembali ke utas panggilan. Jadi kode pada pernyataan foreach selalu berada di utas UI.

Masuk akal jika Anda melakukan sesuatu yang mahal dalam permintaan linq di sebelah kanan AsParallel()panggilan, seperti:

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

Apa manfaatnya dari hanya melakukan studi paralel pada computefibonacci?
l --''''''----------------- '' '' '' '' '' '' '15

51

Perbedaannya adalah, B tidak paralel. Satu-satunya hal yang AsParallel()dilakukan adalah membungkusnya IEnumerable, sehingga ketika Anda menggunakan metode LINQ, varian paralelnya digunakan. Pembungkus GetEnumerator()(yang digunakan di belakang layar di foreach) bahkan mengembalikan hasil koleksi asli GetEnumerator().

BTW, jika Anda ingin melihat metode di Reflector, AsParallel()ada di System.Linq.ParallelEnumerablekelas di System.Coremajelis. Parallel.ForEach()ada di mscorlibmajelis (namespace System.Threading.Tasks).


Apa yang Anda maksud dengan ... Varian paralelnya digunakan ...?
l --''''''--------- '' '' '' '' '' '' '15

2
@ tanda baca Itu, misalnya, ketika Anda menulis .Select(), ia memanggil ParallelEnumerable.Select()dan bukan yang normal Enumerable.Select().
svick

50

Metode kedua tidak akan paralel dengan cara yang benar untuk menggunakan AsParallel () pada contoh Anda

IEnumerable<string> items = ...

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

3
Mengapa menggunakan kombinasi asparalel bersama forall, bukan hanya foreach?
l --''''''--------- '' '' '' '' '' '' '15
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.