Question

http://msdn.microsoft.com/en-us/library/ dd988458.aspx

UPD :

, nous allons discuter de cet article alors: http://msdn.microsoft. com / fr-fr / bibliothèque / dd997396.aspx

Je l'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 ne change que task.IsCanceled, qui est inutile IMHO, en raison je devrais encore à mettre en œuvre tout manuellement

Était-ce utile?

La solution

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

Considérez 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 le tokenSource.Cancel() d'appel est émis avant que la tâche a été effectivement commencé, vous allouer encore un thread de travail de pool de threads, de sorte que vous allez perdre des ressources système.

Mais lorsque vous spécifiez l'argument jeton dans Task.Factory.StartNew, la tâche sera immédiatement annulée, sans allouer un thread de travail.

Autres conseils

Annulation avec des tâches est toujours coopératif. Vous ne voudriez pas un fil à mort au milieu d'une opération critique. Vous devez vérifier pour elle.

CancellationTokens sont mieux que simples constructions comme un ManualResetEvent pour l'arrêt de signalisation d'une opération parce que vous pouvez mettre en cascade ou les combiner, par exemple, vous pouvez avoir l'un pour l'arrêt de l'application générale et vous pouvez le combiner avec un pour l'annulation d'une tâche particulière. La tâche n'a qu'à regarder l'un CancellationToken mais vous pouvez l'annuler à partir soit CancellationTokenSource.

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