2010-02-18 33 views
7

tôi có một phương pháp mở rộng cho IEnumerable, sau đó lặp lại thông qua bộ sưu tập, thực hiện công việc kinh doanh của mình và sau đó trả về một IEnumerable mới.trả về null với PLINQ

Tôi đã cố gắng sử dụng PLINQ sử dụng .AsParallel(). ForAll() tăng tốc độ lặp lại đáng kể là null.

Tôi cho rằng điều này có thể là do nó trả lại bộ sưu tập trước khi tất cả 'doanh nghiệp' có cơ hội hoàn thành? nếu tôi gỡ lỗi và đặt trong một breakpoint, không có null.

có loại phương pháp 'chờ cho hoạt động này được hoàn thành' mà tôi nên sử dụng không?

CHỈNH SỬA: để rõ ràng hơn một chút, có logic nghiệp vụ trong forall, sửa đổi thuộc tính, v.v. cần phải có một hành động lặp, thay vì chỉ đơn giản là chọn một cái gì đó.

+0

bạn có thể chỉ cho chúng tôi một mẫu mã? –

+0

ParallelEnumerable . AllAll() không trả lại bất kỳ thứ gì (void ForAll (...)), không phải là một số không thể đếm được: - nếu bạn đang sử dụng ForAll, bạn không trả về số ... Bạn cần hiển thị mã. –

+0

xin lỗi vì sự mơ hồ. phương thức trả về bộ sưu tập, chứ không phải forall. – benpage

Trả lời

1

Câu trả lời tùy thuộc vào ý của bạn là trả về, vì phương thức ForAll không trả lại bất kỳ điều gì. Nó gọi đại biểu bạn chỉ định song song cho tất cả các phần tử của bộ sưu tập. Tôi sẽ giả sử rằng mã của bạn trông như thế này:

data.AsParallel().ForAll(() => /* calculate and store result somewhere */); 
// more code 

Phương pháp ForAll không chờ đợi cho tất cả các đại biểu để hoàn thành, vì vậy more code có thể thực hiện trước khi tất cả các đại biểu đầy đủ (và bạn cũng cần phải cẩn thận trong store result somewhere ! chút, bởi vì nó có thể chạy đồng thời cho nhiều đại biểu)

tôi nghĩ rằng các mã có thể được viết lại thanh lịch hơn bằng cách sử dụng phương pháp Select:

var res = data.AsParallel().Select(() => /* calculate the result */); 

Trong cas này e, đại biểu chỉ trả về kết quả. Phương thức Where thu thập tất cả các kết quả và khi bạn lặp lại trên trả về IEnumerable, nó đảm bảo rằng tất cả các đại biểu đã hoàn thành việc tính toán.

+0

cảm ơn tom - xin lỗi vì sự mơ hồ, phương thức trả về bộ sưu tập, nó không thể được trả về từ forall - có quá nhiều logic nghiệp vụ trong đó. – benpage

+0

Trong trường hợp đó, bạn cần phải thực sự cẩn thận, bởi vì các hành động đang thực hiện đồng thời - bạn gần như chắc chắn cần một số khóa. PLINQ được sử dụng tốt nhất khi bạn có mã "trả về kết quả" (còn gọi là hàm) thay vì "sửa đổi trạng thái" (còn gọi là bắt buộc). –

0

ForAll() không thực hiện hợp nhất và trả về ngay lập tức. Parallel.ForEach() có lẽ là chức năng bạn đang tìm kiếm.

tức là thay vì:

collection.AsParallel().ForAll(t=>t.doWork());

cái gì đó như

Parallel.ForEach(collection.AsParallel(), t=>t.doWork());

+0

hmmm .. không tốt - Parallel.ForEach (bộ sưu tập, t => t.doWOrk()); gây ra cùng một vấn đề, và Parallel.ForEach (collection.AsParallel(), t => t.doWork()); ném một ngoại lệ tổng hợp – benpage

+0

Odd ... 'Parallel.ForEach()' trả về một 'ParallelLoopResult' có một thuộc tính' IsCompleted' mà bạn có thể kiểm tra. Mặc dù vậy, tôi sẽ xem xét nội dung của 'AggregateException', có lẽ một cái gì đó không xảy ra một cách chính xác trong hàm' doWork() 'của bạn. – Tanzelax