2016-03-21 28 views
8

Oprócz najbardziej rozpowszechnioną formą nazywając TaskFactory.StartNew tylko parametru „działanie” (1) https://msdn.microsoft.com/en-us/library/dd321439(v=vs.110).aspxPo co przekazywać token anulowania do TaskFactory.StartNew?

my Alše mieć jedną metodę, która akceptuje dodatkowy parametr jako „anulowanie Token” (2) https://msdn.microsoft.com/en-us/library/dd988458.aspx

Moje pytanie brzmi: dlaczego powinniśmy użyć połączenia (2) zamiast połączenia (1)?

Znaczy, przykład w MSDN na stronie (2) będzie również działać, jeśli nie zdam odwołaniu token jako parametr (ponieważ zmienna Token jest dostępny z funkcji delegata coś takiego:.

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(); 

Więc czy jest coś dzieje się pod spodem, gdy mijam anulowania token Task.Factory.StartNew?

Dzięki

Odpowiedz

7

Dwie rzeczy się wydarzy.

  1. Jeśli token został anulowany przed wywołaniem funkcji StartNew, to nigdy nie uruchomi wątku, a zadanie będzie w stanie Canceled.
  2. Jeśli podniesiono OperationCanceledException z wewnątrz zadania i ten wyjątek został przekazany w tym samym tokenie, co StartNew, spowoduje ono, że zwrócone zadanie zostanie wprowadzone do stanu Cancelled. Jeśli token powiązany z wyjątkiem jest innym tokenem lub nie przekazałeś tokena w zadaniu, wejdzie on w stan Faulted.

P.S. Nigdy nie należy dzwonić pod numer Task.Factory.StartNew, nie przechodząc pod numerem TaskScheduler, ponieważ w przeciwnym razie można go łatwo uzyskać: cause you to run code on the UI thread that you expected to run on a background thread. Zamiast tego należy użyć Task.Run(, chyba że bezwzględnie trzeba użyć StartNew, Task.Run ma to samo zachowanie CancellationToken jako StartNew.

+0

Dziękuję za szerzenie słowa o tym, że nie używam 'Task.Factory' – kai

Powiązane problemy