2010-09-24 26 views
126

Erg, tôi đang cố gắng tìm hai phương pháp này trong BCL bằng cách sử dụng Reflector, nhưng không thể định vị chúng. Sự khác nhau giữa hai đoạn mã này là gì?Parallel.ForEach() và foreach (IEnumerable <T> .AsParallel())

A:

IEnumerable<string> items = ... 

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

B:

IEnumerable<string> items = ... 

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

Có những hậu quả khác nhau của việc sử dụng một trong khác không? (Giả sử rằng bất cứ điều gì tôi đang làm trong các vật thể có khung của cả hai ví dụ đều là an toàn.)

Trả lời

138

Họ làm điều gì đó khá khác biệt.

Người đầu tiên lấy đại biểu ẩn danh và chạy nhiều luồng trên mã này song song cho tất cả các mục khác nhau.

Cách thứ hai không hữu ích trong trường hợp này. Tóm lại, nó được thiết kế để thực hiện một truy vấn trên nhiều luồng, và kết hợp kết quả, và đưa nó trở lại luồng gọi. Vì vậy, mã trên báo cáo foreach luôn ở trên chuỗi giao diện người dùng.

Nó chỉ có ý nghĩa nếu bạn làm điều gì đó đắt tiền trong truy vấn LINQ to phía bên phải của AsParallel() cuộc gọi, như:

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

lợi ích hơn chỉ đơn giản là làm một foreach song song trên computefibonacci là gì? –

46

Sự khác biệt là, B được không song song. Điều duy nhất AsParallel() là nó kết thúc tốt đẹp xung quanh một IEnumerable, do đó khi bạn sử dụng các phương pháp LINQ, các biến thể song song của chúng được sử dụng. GetEnumerator() của trình bao bọc (được sử dụng sau hậu trường trong foreach) thậm chí trả lại kết quả của bộ sưu tập gốc GetEnumerator().

BTW, nếu bạn muốn xem xét các phương pháp trong Reflector, AsParallel() nằm trong lớp System.Linq.ParallelEnumerable trong assembly System.Core. Parallel.ForEach() nằm trong bộ phận mscorlib (không gian tên System.Threading.Tasks).

+0

Ý của bạn là gì ... Các biến thể song song của chúng được sử dụng ...? –

+1

@punctuation Ví dụ, khi bạn viết '.Select()', nó gọi 'ParallelEnumerable.Select()' và không phải là 'Enumerable.Select()' bình thường. – svick

42

Phương pháp thứ hai sẽ không được song song cách chính xác để sử dụng AsParallel() trong ví dụ của bạn sẽ là

IEnumerable<string> items = ... 

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

Tại sao sử dụng sự kết hợp của vô song cùng với forall thay vì chỉ đơn giản là foreach? –

Các vấn đề liên quan