web-dev-qa-db-fra.com

Best Practice LongRunning Task creation

Est-ce une bonne conception pour un thread d'arrière-plan qui doit être exécuté à l'aide de l'API de tâche dans .Net 4? Ma seule préoccupation est si nous voulons annuler cette tâche, comment je le ferais? Je sais que je peux simplement définir ProgramEnding sur true mais je sais qu'il y a un CancellationToken dans l'API de tâche.

Il s'agit simplement d'un exemple de code afin qu'un thread soit ajouté à une collection et qu'un autre thread en soit supprimé. La tâche est configurée en tant que LongRunning car elle doit être exécutée en continu pendant l'exécution du programme

private void RemoveFromBlockingCollection()
{
    while (!ProgramEnding)
    {
       foreach (var x in DataInQueue.GetConsumingEnumerable())
       {
          Console.WriteLine("Task={0}, obj={1}, Thread={2}"
                          , Task.CurrentId, x + " Removed"
                          , Thread.CurrentThread.ManagedThreadId);
       }
    }
}

private void button1_Click(object sender, EventArgs e)
{
   DataInQueue = new BlockingCollection<string>();
   var t9 = Task.Factory.StartNew(RemoveFromBlockingCollection
                                 , TaskCreationOptions.LongRunning);

   for (int i = 0; i < 100; i++)
   {
     DataInQueue.Add(i.ToString());
     Console.WriteLine("Task={0}, obj={1}, Thread={2}", 
                       Task.CurrentId, i + " Added", 
                       Thread.CurrentThread.ManagedThreadId);
     Thread.Sleep(100);
   }
   ProgramEnding = true;
}

PDATE: J'ai trouvé que je pouvais supprimer le booléen ProgramEnding et utiliser DataInQueue.CompleteAdding qui mettait fin au thread.

25
Jon

Comme vous l'avez déjà mentionné, vous pouvez utiliser le CancellationToken. Faites-le de cette façon:

var cancellationTokenSource = new CancellationTokenSource();
Task.Factory.StartNew(RemoveFromBlockingCollection
                      , TaskCreationOptions.LongRunning
                      , cancellationTokenSource.Token);  

Et plus tard dans votre code, vous pouvez annuler la tâche avec:

cancellationTokenSource.Cancel();

Dans votre longue tâche, vous pouvez demander le jeton, si l'annulation a été demandée:

if (cancellationTokenSource.Token.IsCancellationRequested)
22
Fischermaen