2013-04-16 24 views
5

Sự khác biệt giữa các hoạt động hủy với hoạt động loopState (Break/Stop) là gì?parallel.foreach - loopState.Stop() so với hủy bỏ

private static CancellationTokenSource cts; 
public static loopingMethod() 
{ 
cts = new CancellationTokenSource(); 
try 
{ 
    ParallelOptions pOptions = new ParallelOptions(); 
    pOptions.MaxDegreeOfParallelism = 4; 
    pOptions.CancellationToken = cts.Token; 
    Parallel.ForEach(dictObj, pOptions, (KVP, loopState) => 
    { 
     pOptions.CancellationToken.ThrowIfCancellationRequested(); 
     parallelDoWork(KVP.Key, KVP.Value, loopState); 
    }); //End of Parallel.ForEach loop 
} 
catch (OperationCanceledException e) 
{ 
//Catestrophic Failure 
return -99; 
} 
} 

public static void parallelDoWork(string Id, string Value, ParallelLoopState loopState) 
{ 
    try{ 
     throw new exception("kill loop"); 
    } 
    catch(exception ex) 
    { 
     if(ex.message == "kill loop") 
     { 
      cts.Cancel(); 
      //Or do I use loopState here? 
     } 
    } 
} 

Tại sao tôi muốn sử dụng các hoạt động ParallelOptions Hủy so với loopState.Break(); hoặc loopState.Stop(); hoặc ngược lại?

Trả lời

2

Xem này article

"Thiết lập một mã thông báo hủy cho phép bạn hủy bỏ Gọi (nhớ rằng khi một đại biểu ném một ngoại lệ, các ngoại lệ được nuốt và chỉ tái ném bởi Invoke sau khi tất cả đại biểu khác đã được được thực hiện). "

Kịch bản 1. Hãy tưởng tượng bạn có người dùng sắp gửi tin nhắn cho tất cả bạn bè cũ [girl | boy]. Họ nhấp vào gửi và sau đó họ đến với giác quan của họ và muốn hủy bỏ nó. Bằng cách sử dụng mã thông báo hủy, họ có thể chặn thêm các tin nhắn khác. Vì vậy, nếu bạn có một quy trình chạy dài được phép hủy, hãy sử dụng mã thông báo hủy.

Kịch bản 2 Mặt khác, nếu bạn không muốn quá trình bị gián đoạn, hãy sử dụng ngoại lệ trạng thái vòng lặp bình thường để các ngoại lệ sẽ bị nuốt cho đến khi tất cả các chuỗi kết thúc.

Kịch bản 3 Nếu bạn có quá trình I/O chuyên sâu, thì có thể bạn muốn sử dụng async/await và không song song.foreach. Hãy xem task-based asynchronous pattern của Microsoft.

+0

Tôi không chắc chắn nếu nó trả lời câu hỏi ban đầu của khi tôi sẽ sử dụng loopState qua hủy bỏ ... Bạn có thể chia nhỏ câu trả lời này và giải thích nó nhiều hơn? – webdad3

+0

Tôi đánh giá cao các kịch bản khác nhau. Điều này có ý nghĩa hơn với tôi. – webdad3

2

ParallelLoopState.Break/Stop có ngữ nghĩa được xác định rõ cụ thể cho việc thực hiện vòng lặp. I E. bằng cách sử dụng chúng, bạn có thể rất cụ thể về cách bạn muốn vòng lặp kết thúc. Mặt khác, CancellationToken là cơ chế dừng chung trong TPL, vì vậy nó không có gì đặc biệt cho các vòng lặp song song. Lợi thế của việc sử dụng mã thông báo là nó có thể được chia sẻ giữa các tính năng TPL khác, vì vậy bạn có thể có một nhiệm vụ và một vòng lặp được kiểm soát bởi cùng một mã thông báo.

+0

Trên thực tế, CancellationToken có một hiệu ứng đặc biệt trên các vòng lặp song song. Nếu ParallelOptions.CancellationToken bị hủy, ParallelLoopState.ShouldExitCurrentIteration trở thành false. Vì vậy, một nhiệm vụ chạy dài (có thể không bị hủy bởi vòng lặp) có thể kiểm tra thuộc tính này và ngừng hoạt động của nó. https://msdn.microsoft.com/en-us/library/system.threading.tasks.parallelloopstate.shouldexitcurrentiteration(v=vs.110).aspx –