2016-03-21 25 views
8

Oltre la forma più comune di chiamare TaskFactory.StartNew con il solo parametro "azione" (1) https://msdn.microsoft.com/en-us/library/dd321439(v=vs.110).aspxPerché passare il token di cancellazione a TaskFactory.StartNew?

abbiamo alse avere un metodo che accetta un parametro in più come il "Annullamento Token" (2) https://msdn.microsoft.com/en-us/library/dd988458.aspx

La mia domanda è, perché dovremmo usare la chiamata (2) invece di chiamare (1)?

Voglio dire, l'esempio in MSDN per la pagina (2) potrebbe anche funzionare se non supero la cancellazione token come parametro (perché il token variabile è accessibile dalla funzione di delegato Qualcosa di simile a:.

var tokenSource = new CancellationTokenSource(); 
     var token = tokenSource.Token; 
     var files = new List<Tuple<string, string, long, DateTime>>(); 

     var t = Task.Factory.StartNew(() => { string dir = "C:\\Windows\\System32\\"; 
           object obj = new Object(); 
           if (Directory.Exists(dir)) { 
            Parallel.ForEach(Directory.GetFiles(dir), 
            f => { 
              if (token.IsCancellationRequested) 
               token.ThrowIfCancellationRequested(); 
              var fi = new FileInfo(f); 
              lock(obj) { 
               files.Add(Tuple.Create(fi.Name, fi.DirectoryName, fi.Length, fi.LastWriteTimeUtc));   
              } 
             }); 
           } 
           } 
         ); //note that I removed the ", token" from here 
     tokenSource.Cancel(); 

Quindi c'è qualcosa accadendo sotto quando passo gettone cancellazione di Task.Factory.StartNew?

Grazie

risposta

7

Due cose accadranno.

  1. Se il token è stato cancellato prima dell'avvio di StartNew, non avvierà mai il thread e l'attività sarà nello stato Canceled.
  2. Se viene sollevata una OperationCanceledException dall'interno dell'attività e tale eccezione è stata inoltrata nello stesso token di StartNew, l'attività restituita entrerà nello stato Cancelled. Se il token associato all'eccezione è un token diverso o se non si è passato un token nell'attività, verrà inserito lo stato Faulted.

P.S. Non si dovrebbe mai chiamare Task.Factory.StartNew senza passare in un TaskScheduler perché se non lo si può facilmente cause you to run code on the UI thread that you expected to run on a background thread. Utilizzare invece Task.Run( a meno che non si debba utilizzare in modo impeccabile StartNew, Task.Run ha lo stesso comportamento CancellationToken come StartNew.

+0

Grazie per aver diffuso la parola sul non utilizzo di 'Task.Factory' – kai