2012-06-01 89 views
19

下面是一個示例代碼,它創建了一個模擬長時間運行的進程的新任務。沒有什麼太多的任務是純粹關注取消功能的。我使用取消令牌來取消任務,並且代碼正常工作爲了我。將CancellationToken傳遞給Task類的構造函數有什麼用?

 CancellationTokenSource CTS= new CancellationTokenSource(); 

     Task<Boolean> PTask = new Task<Boolean>(() => 
     { 
      while (true) 
      { 
       if (!CTS.Token.IsCancellationRequested) 
       { 
        Thread.Sleep(5000); 
       } 
       else{Console.WriteLine("Thread Cancelled");break;} 
      } 
      return true; 

     }, CTS.Token, TaskCreationOptions.None); 

     PTask.Start(); 
     Console.WriteLine("Hit Enter to cancel the Secondary thread you have started"); 
     Console.ReadLine(); 
     CTS.Cancel(); 
     System.Console.WriteLine(PTask.Result); 

    } 
} 

但onething是我無法理解的是,被傳遞到任務Constructor.What令牌參數(CTS.Token)是實際使用傳遞參數,當我其實可以取消任務即使沒有將令牌傳遞給構造函數。

下面是一個略有修改的版本,沒有token參數。

 CancellationTokenSource CTS= new CancellationTokenSource(); 
     Task<Boolean> PTask = new Task<Boolean>(() => 
     { 
      while (true) 
      { 
       if (!CTS.Token.IsCancellationRequested) 
       { 
        Thread.Sleep(5000); 
       } 
       else 
       { 
        Console.WriteLine("Thread Cancelled"); 
        break; 
       } 
     }; 
+1

我會推薦閱讀:http://blogs.msdn.com/b/pfxteam/archive/2009/05/22/9635790.aspx – Slugart

回答

35

UPDATE: 以下msdn問題描述的原因:與任務令牌關聯

傳遞令牌到StartNew。 這有兩個主要優點:

  1. 如果令牌有取消 任務之前,請開始執行,任務將無法執行 。它將立即 轉換到已取消,而不是過渡到運行。這樣可以避免運行任務的成本,如果 只是在運行時纔會被取消。

  2. 如果 任務的身體也監測取消標記並拋出 OperationCanceledException包含令牌(這是什麼 ThrowIfCancellationRequested那樣),那麼當任務看到OCE, 它檢查是否OCE的令牌匹配任務的標記。如果它是 ,那麼此例外情況將視爲確認合作伙伴取消,並且任務轉換爲取消狀態(而不是故障狀態的 )。

+0

你說的iscancelrequest與主令牌檢查線程不安全。 –

+0

我看不到任何將令牌傳遞給構造函數的其他原因,但是如果你問我是否100%確定;不好。 – daryal

+0

我已更新,實際上這與線程安全無關。 – daryal

相關問題