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.)

SnickersAreMyFave
sumber

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));
svick
sumber
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).

svick
sumber
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
});
Scott Chamberlain
sumber
3
Mengapa menggunakan kombinasi asparalel bersama forall, bukan hanya foreach?
l --''''''--------- '' '' '' '' '' '' '15