Question

Certains constructeurs de System.Threading.Tasks.Task prendre un CancellationToken comme paramètre:

CancellationTokenSource source = new CancellationTokenSource();
Task t = new Task (/* method */, source.Token);

Ce qui me déconcerte à ce sujet est qu'il n'y a aucun moyen de dans le corps de méthode pour obtenir effectivement le jeton passé dans (par exemple, rien comme Task.CurrentTask.CancellationToken). Le jeton doit être fourni par le biais d'un autre mécanisme, tel que l'objet d'état ou capturé dans un lambda.

Dans quel but l'annulation ne fournissant jeton dans le constructeur service?

Était-ce utile?

La solution

En passant ce jeton dans les associés du constructeur tâche avec cette tâche.

citant la réponse de Stephen Toub de MSDN :

  

Cela a deux avantages principaux:

     
      
  1. Si le jeton a demandé l'annulation avant la Tâche de commencer l'exécution, le Groupe ne sera pas exécuté. Plutôt que le passage à   Running, il va immédiatement la transition vers Canceled. Cela permet d'éviter la   frais de fonctionnement de la tâche si elle serait tout simplement annulé en cours d'exécution   de toute façon.
  2.   
  3. Si le corps de la tâche surveille également le jeton d'annulation et jette un OperationCanceledException contenant ce jeton   (Qui est ce que ThrowIfCancellationRequested fait), puis lorsque la tâche   voit que OperationCanceledException, il vérifie si les matchs jeton du OperationCanceledException de la Task   jeton. Dans le cas contraire, cette exception est considérée comme une reconnaissance de   annulation coopérative et les transitions vers la tâche Annulée   Etat (plutôt que l'état Faulted).
  4.   

Autres conseils

Le constructeur utilise le jeton pour l'annulation de manutention interne. Si votre code souhaite l'accès au jeton que vous êtes responsable de le transmettre à vous-même. Je recommande vivement de lire le Programmation parallèle avec le livre Microsoft .NET à CodePlex.

Exemple d'utilisation du CTS du livre:

CancellationTokenSource cts = new CancellationTokenSource();
CancellationToken token = cts.Token;

Task myTask = Task.Factory.StartNew(() =>
{
    for (...)
    {
        token.ThrowIfCancellationRequested();

        // Body of for loop.
    }
}, token);

// ... elsewhere ...
cts.Cancel();

L'annulation est pas simple cas que beaucoup pourraient penser. Certaines des subtilités sont expliquées dans ce billet de blog sur msdn:

Par exemple:

  

Dans certaines situations dans les extensions parallèles et dans d'autres systèmes, il   est nécessaire de se réveiller une méthode bloquée pour des raisons qui ne sont pas dus   à l'annulation explicite par un utilisateur. Par exemple, si un thread est   bloqué sur blockingCollection.Take () en raison de la collection étant vide   et un autre thread appelle la suite   blockingCollection.CompleteAdding (), le premier appel doit se réveiller   et jeter un InvalidOperationException pour représenter un incorrect   utilisation.

http://blogs.msdn.com /b/pfxteam/archive/2009/06/22/9791840.aspx

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top