2010-09-11 4 views
12

http://msdn.microsoft.com/en-us/library/dd988458.aspxÀ quoi sert "cancellationToken" dans TaskFactory.StartNew()?

UPD:

donc, nous allons discuter de cet article alors: http://msdn.microsoft.com/en-us/library/dd997396.aspx

J'ai changé ce code un peu:

static void Main() 
    { 

     var tokenSource2 = new CancellationTokenSource(); 
     CancellationToken ct = tokenSource2.Token; 

     var task = Task.Factory.StartNew(() => 
     { 

      // Were we already canceled? 
      ct.ThrowIfCancellationRequested(); 

      bool moreToDo = true; 
      Thread.Sleep(5000); 
      while (moreToDo) 
      { 

       // Poll on this property if you have to do 
       // other cleanup before throwing. 
       if (ct.IsCancellationRequested) 
       { 
        Console.WriteLine("exit"); 
        // Clean up here, then... 
        ct.ThrowIfCancellationRequested(); 
       } 

      } 
     }, tokenSource2.Token); // this parameter useless 

     Console.WriteLine("sleep"); 
     Thread.Sleep(2000); 
     Console.WriteLine("cancel"); 

     tokenSource2.Cancel(); 

     // Just continue on this thread, or Wait/WaitAll with try-catch: 
     try 
     { 
      task.Wait(); 
     } 
     catch (AggregateException e) 
     { 
      foreach (var v in e.InnerExceptions) 
      { 
       Console.WriteLine(e.Message + " " + v.Message); 
      } 
     } 

     Console.ReadKey(); 
    } 

UPD: Eh bien, cela change seulement task.IsCanceled, qui est imho inutile, en raison de je devrais encore implémenter tout manuellement.

+0

Voir [Annulation de tâche] (http://msdn.microsoft.com/fr-fr/library/dd997396.aspx). –

+2

Je l'ai vu. "}, tokenSource2.Token)" - cet argument ne change rien. Soit nous avons ou non ce Token passé - nous obtiendrons une exception, car 'ct' est géré par la fermeture. – zerkms

+1

Dommage qu'il n'y ait pas vraiment de réponse à cette question, je m'interroge aussi sur la nécessité de cet argument ... il semble totalement inutile pour le moment. –

Répondre

28

En raison de commentaires, je poste une autre réponse.

Consultez le code suivant:

var tokenSource = new CancellationTokenSource(); 
CancellationToken ct = tokenSource.Token; 

tokenSource.Cancel(); 

var task = Task.Factory.StartNew(() => 
{  
    // Were we already canceled? 
    ct.ThrowIfCancellationRequested(); 
    // do some processing 
}); 

Même si l'appel tokenSource.Cancel() est émis avant que la tâche a été effectivement commencé, vous allouez encore un thread de travail de pool de threads, de sorte que vous allez perdre des ressources système . Mais lorsque vous spécifiez un argument de jeton dans Task.Factory.StartNew, la tâche sera immédiatement annulée, sans allouer de thread de travail.

+2

Cela devrait probablement être la réponse acceptée - posté en votre nom ci-dessus. Une question - existe-t-il un moyen d'obtenir le jeton d'annulation de la tâche en cours qui a été transmis? Un peu comme l'équivalent de Dispatcher.CurrentDispatcher? – BrainSlugs83

+2

Cela a trébuché pendant un certain temps. Existe-t-il une documentation MSDN qui confirme cela? –

+1

Voir http://stackoverflow.com/a/3713113/2394945 –

3

Annulation avec Tâches est toujours coopératif. Vous ne voudriez pas qu'un fil soit tué au milieu d'une opération critique. Vous devez vérifier pour cela. Les temporisations sont mieux que des constructions plus simples comme ManualResetEvent pour signaler l'arrêt d'une opération car vous pouvez les cascader ou les combiner, par exemple, vous pouvez en avoir une pour l'arrêt global de l'application et vous pouvez la combiner avec une pour annuler une tâche particulière . La tâche doit seulement regarder l'un CancellationToken mais vous pouvez l'annuler de CancellationTokenSource.

+0

alors, comment puis-je obtenir cet argument de jeton dans le travail()? – zerkms

+1

Eh bien, vous pouvez le transmettre en utilisant http://msdn.microsoft.com/en-us/library/dd780315.aspx mais l'utilité REAL des jetons d'annulation entre en jeu lorsque vous commencez à implémenter votre propre 'TaskFactory' et que vous voulez avoir des jetons d'annulation en cascade et autres semblables et alors c'est beaucoup plus puissant qu'un simple 'ManualResetEvent' ou similaire. –

+0

@zerkms: Lisez également [cancel] (http://msdn.microsoft.com/en-us/library/dd997364.aspx) sur MSDN, qui donne une vue plus détaillée de la structure d'annulation unifiée. L'annulation de tâche est la manière dont les objets 'Task' utilisent l'annulation. Si vous lisez l'article d'annulation "grande image", alors les avantages devraient devenir plus clairs. –