2016-03-21 61 views
8

除了要求TaskFactory.StartNew僅與「動作」參數的最常見的形式 (1)https://msdn.microsoft.com/en-us/library/dd321439(v=vs.110).aspx爲什麼要將取消令牌傳遞給TaskFactory.StartNew?

我們ALSE有一個接受一個額外的參數爲「對消令牌」 (2)https://msdn.microsoft.com/en-us/library/dd988458.aspx

一個方法

我的問題是,爲什麼我們應該使用call(2)而不是call(1)?

我的意思是,對於頁面中的MSDN的例子(2)將也,如果我沒有通過取消標記爲參數(因爲變量令牌是由委託函數訪問的工作是這樣:

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

所以有什麼情況發生底下當我通過取消標記以Task.Factory.StartNew?

感謝

回答

7

兩件事情會發生。

  1. 如果在調用StartNew之前令牌已被取消,它將永遠不會啓動線程並且任務將處於Canceled狀態。
  2. 如果OperationCanceledException是從任務內部引發的,並且該異常以與StartNew相同的標記傳遞,則它將導致返回的任務進入Cancelled狀態。如果與異常關聯的令牌是不同的令牌,或者您未在任務中傳遞令牌,則會輸入Faulted狀態。

P.S.如果不通過TaskScheduler,您永遠不應該撥打Task.Factory.StartNew,因爲如果您不這樣做,它可以很容易地cause you to run code on the UI thread that you expected to run on a background thread。除非您絕對需要使用StartNewTask.RunStartNew具有相同的CancellationToken行爲,否則請使用Task.Run(

+0

感謝您傳播有關不使用'Task.Factory' – kai

相關問題