2011-10-27 17 views
21

Si tratta di una buona progettazione per un thread in background che deve essere eseguito utilizzando l'API delle attività in .Net 4? La mia unica preoccupazione è se vogliamo cancellare quel compito come lo farei? So che posso semplicemente impostare ProgramEnding su true ma so che c'è un CancellationToken nell'API attività.Best Practice LongRunning Creazione attività

Questo è solo un esempio di codice di esempio in modo che un thread verrà aggiunto a una raccolta e un altro thread verrà rimosso da esso. La task è configurato come LongRunning come questo deve essere sempre in funzione, mentre il programma è in esecuzione

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

UPDATE: ho scoperto che posso togliere il booleano ProgramEnding e utilizzare DataInQueue.CompleteAdding che che portano il filo una fine.

risposta

18

Come già accennato, è possibile utilizzare il metodo di annullamento. Farlo in questo modo:

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

E più avanti nel codice, è possibile annullare l'operazione con:

cancellationTokenSource.Cancel(); 

nel vostro compito lungo in esecuzione si può chiedere il motivo, se è stata richiesta la cancellazione:

if (cancellationTokenSource.Token.IsCancellationRequested) 
+0

L'uso di un booleano per mantenere in vita il thread è una procedura consigliata o c'è una chiamata API? Ho scoperto che posso usare il metodo CompleteAdding su BlockingCollection ma se non sto usando BlockingCollection e non faccio altro, il booleano sarebbe accpetable? – Jon

+0

Sì, funzionerebbe. O usi il CancellationToken che ho menzionato sopra. – Fischermaen

+0

Posso usarlo per cancellare il thread che stavo chiedendo alla tua opinione di mantenere un thread in esecuzione? – Jon