2013-04-16 3 views
5

Quelle est la différence entre les opérations d'annulation et l'opération loopState (Break/Stop)?parallel.foreach - loopState.Stop() versus Annulation

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

Pourquoi voudrais-je utiliser la ParallelOptions opération d'annulation par rapport à la loopState.Break(); ou loopState.Stop(); ou vice versa?

Répondre

2

Voir cette article

« Définition d'un jeton d'annulation permet de interrompez Invoke (rappelez-vous que lorsqu'un délégué lève une exception, l'exception est avalée et que relancées par Invoke après que tous les autres délégués ont été exécuté). "

Scénario 1. Imaginez que vous ayez un utilisateur sur le point d'envoyer des messages à tous les amis de [girl | boy]. Ils cliquent sur envoyer, puis ils viennent à leurs sens et veulent l'annuler. En utilisant le jeton d'annulation, ils peuvent empêcher d'autres messages de sortir. Donc, si vous avez un long processus qui peut être annulé, utilisez le jeton d'annulation. Par contre, si vous ne voulez pas qu'un processus soit interrompu, utilisez les exceptions normales d'état de boucle pour que les exceptions soient avalées jusqu'à ce que tous les threads soient terminés.

Scénario 3 Si vous utilisez un processus intensif en E/S, vous souhaitez probablement utiliser async/await et non parallel.foreach. Consultez le task-based asynchronous pattern de Microsoft.

+0

Je ne suis pas sûr si elle répond à la question originale de quand aurais-je utilisé loopState sur l'annulation ... Pouvez-vous décomposer cette réponse et l'expliquer plus? – webdad3

+0

J'apprécie les différents scénarios. Cela a beaucoup plus de sens pour moi. – webdad3

2

ParallelLoopState.Break/Stop ont une sémantique bien définie spécifique à l'exécution de la boucle. C'est à dire. en les utilisant, vous pouvez être très précis sur la façon dont vous voulez que la boucle se termine. D'autre part, un CancellationToken est le mécanisme d'arrêt générique dans TPL, donc il ne fait rien de spécial pour les boucles parallèles. L'avantage de l'utilisation du jeton est qu'il peut être partagé entre d'autres fonctionnalités TPL, de sorte que vous pouvez avoir une tâche et une boucle contrôlées par le même jeton.

+0

En fait, CancellationToken a un effet spécial sur les boucles parallèles. Si ParallelOptions.CancellationToken est annulé, ParallelLoopState.ShouldExitCurrentIteration devient false. Ainsi, une tâche longue (qui n'a peut-être pas été annulée par la boucle) peut vérifier cette propriété et arrêter son travail. https://msdn.microsoft.com/en-us/library/system.threading.tasks.parallelloopstate.shouldexitcurrentiteration(v=vs.110).aspx –