Parallel.ForEach () so với foreach (IEnumerable <T> .AsParallel ())


143

Erg, tôi đang cố gắng tìm hai phương thức này trong BCL bằng Reflector, nhưng không thể xác định được chúng. Sự khác biệt giữa hai đoạn này là gì?

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 cái này hơn cái kia? (Giả sử rằng bất cứ điều gì tôi đang làm trong phần thân của cả hai ví dụ đều an toàn cho chuỗi.)

Câu trả lời:


148

Họ làm một cái gì đó khá khác nhau.

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

Cái thứ hai không hữu ích lắm trong kịch bản này. Tóm lại, nó được dự định để 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ó một lần nữa cho chuỗi gọi. Vì vậy, mã trên câu lệnh foreach luôn nằm trong luồng UI.

Nó chỉ có ý nghĩa nếu bạn thực hiện một cái gì đó đắt tiền trong truy vấn linq ở bên phải của AsParallel()cuộc gọi, như:

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

Lợi ích gì khi chỉ đơn giản là thực hiện một nghiên cứu song song về computefiborie?
l --'''''--------- '' '' '' '' '' ''

51

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

BTW, nếu bạn muốn xem các phương thức trong Reflector, AsParallel()nằm trong System.Linq.ParallelEnumerablelớp trong cụm System.Core. Parallel.ForEach()là trong mscorlibhội đồng (không gian tên System.Threading.Tasks).


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

2
@ chấm câu Điều đó, ví dụ, khi bạn viết .Select(), nó gọi ParallelEnumerable.Select()và không bình thường Enumerable.Select().
Svick

50

Phương thức thứ hai sẽ không 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
});

3
Tại sao sử dụng sự kết hợp của aspool cùng với forall thay vì chỉ đơn giản là foreach?
l --'''''--------- '' '' '' '' '' ''
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.