Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

parallel.foreach - loopState.Stop() versus Cancellation

What is the difference between the Cancellation operations versus the loopState operation (Break/Stop)?

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?
       }
   }
}

Why would I want to use the ParallelOptions Cancellation operation versus the loopState.Break(); or loopState.Stop(); or vice versa?

like image 532
webdad3 Avatar asked Apr 16 '13 22:04

webdad3


2 Answers

See this article

"Setting a cancellation token allows you to abort Invoke (remember that when a delegate throws an exception, the exception is swallowed and only re-thrown by Invoke after all other delegates have been executed)."

Scenario 1. Imagine you have a user about to send messages to all ex-[girl|boy]friends. They click send and then they come to their senses and want to cancel it. By using the cancellation token they are able to stop further messages from going out. So if you have a long running process that is allowed to be cancelled, use the cancellation token.

Scenario 2 On the other hand, if you don't want a process to be interrupted, then use normal loop state exceptions so that the exceptions will be swallowed until all threads finish.

Scenario 3 If you have a process that is I/O intensive, then you probably want to be using async/await and not parallel.foreach. Check out Microsoft's task-based asynchronous pattern.

like image 132
What Would Be Cool Avatar answered Sep 18 '22 19:09

What Would Be Cool


ParallelLoopState.Break/Stop have well defined semantics specific to the execution of the loop. I.e. by using these you can be very specific about how you want the loop to terminate. A CancellationToken on the other hand is the generic stop mechanism in TPL, so it does nothing special for parallel loops. The advantage of using the token is that it can be shared among other TPL features, so you could have a task and a loop that are controlled by the same token.

like image 26
Brian Rasmussen Avatar answered Sep 22 '22 19:09

Brian Rasmussen