2015-05-24 21 views
2

有人可以舉一個例子,我應該使用三個參數的下一個方法。使用CancellationTokenSource

var tokenSource = new CancellationTokenSource(); 
var token = tokenSource.Token; 

Task.Factory.StartNew(MyTask, token, token); 

請問您能解釋一下,爲什麼我們需要第三個參數?

+1

什麼是MyTask?第一個標記實際上是MyTask的對象參數嗎?試試:'Task.Factory.StartNew(()=> MyTask(),token)'。 – glenebob

回答

3

StartNew沒有超載,即StartNew(Action, CancellationToken, CancellationToken)。最有可能的是,這裏調用的方法是StartNew(Action<object>, object, CancellationToken)

此重載啓動Action,並將提供的對象(第二個參數)作爲此Action的參數傳遞。

我只能假設原因是因爲Action可以參與CancellationToken提供的合作取消流程。換句話說,它不僅允許任務通過令牌協作取消,還可以在Action中使用它,以便儘快退出執行並可能避免ThreadAbortedException。

var tokenSource = new CancellationTokenSource(); 
var token = tokenSource.Token; 

Task.Factory.StartNew(x => 
{ 
    var token = (CancellationToken)x; 
    for(var item in ReallyBigCollection){ 
     Process(item, token); 
     if(token.IsCancellationRequested) 
      return; 
    } 
}, token, token); 

除非你打算使用CancellationToken,否則沒有太多的理由有CancellationToken。

+1

這是一個.NET的原始方法: public Task StartNew(動作動作,對象狀態,CancellationToken cancellationToken); 謝謝你的例子,但是如果你刪除第三個參數,你的代碼仍然有效。 – Alexander

+0

我仍然不明白爲什麼我們使用第二個「令牌」。 – Alexander

+0

這與線程中止有什麼關係? – svick

2

你似乎對方法簽名本身感到困惑。

your comment,你實際上叫public Task StartNew(Action<object> action, object state, CancellationToken cancellationToken)。但是在打電話時,您正在使用以下Task.Factory.StartNew(MyTask, token, token)

所以,是的,你兩次使用token,你試圖瞭解爲什麼你需要使用兩次token

答案是您正在錯誤地使用重載(或未使用正確的重載)。

如果你看一下method documentation你會看到以下內容:

  • 行動類型:System.Action<Object> - 動作委託異步執行。
  • 狀態類型:System.Object - 包含要由動作委託使用的數據的對象。
  • 的CancellationToken類型:System.Threading.CancellationToken - 將被分配到新的任務

的的CancellationToken所以你基本上是一個傳遞CancellationToken的CancellationToken都和狀態

你不需要同時通過。正如文檔中提到的那樣,第二個參數(「狀態」)是供動作委託使用的數據,並且您傳遞的是CancellationToken。雖然它起作用,但您正在使用一個參數來表示它不一定用於此目的(對於繼承您的代碼的其他人可能會感到困惑)。

如果您沒有數據傳遞給Action,則傳遞null值是完全可以接受的。然後,您可以使用適當的CancellationToken參數進行重載。

0

取消令牌提供給異步操作,以幫助它確定執行某些「取消」事件時執行的步驟。顯然,可以發送空值。

相關問題