問題關聯起來的CancellationToken:有沒有辦法與從async
方法返回的Task
一個CancellationToken
關聯?與異步方法的任務
一般地,如果OperationCancelledException
與CancellationToken
匹配Task
的CancellationToken
拋出Task
將在取消狀態結束。如果它們不匹配,則任務進入斷陷狀態:
void WrongCancellationTokenCausesFault()
{
var cts1 = new CancellationTokenSource();
var cts2 = new CancellationTokenSource();
cts2.Cancel();
// This task will end up in the Faulted state due to the task's CancellationToken not matching the thrown
// OperationCanceledException's token.
var task = Task.Run(() => cts2.Token.ThrowIfCancellationRequested(), cts1.Token);
}
隨着async
/await
,我還沒有找到一個方法來設置方法的Task
的CancellationToken
(進而達到相同類型的功能)。從我的測試,似乎任何OperationCancelledException
將導致async
方法進入已取消狀態:
async Task AsyncMethodWithCancellation(CancellationToken ct)
{
// If ct is cancelled, this will cause the returned Task to be in the Cancelled state
ct.ThrowIfCancellationRequested();
await Task.Delay(1);
// This will cause the returned Task to be in the Cancelled state
var newCts = new CancellationTokenSource();
newCts.Cancel();
newCts.Token.ThrowIfCancellationRequested();
}
這將是很好,有一點更多的控制,因爲如果一個方法,我從我的async
方法調用被取消(我不希望取消 - 即它不是Task
的CancellationToken
),我希望任務進入Faulted狀態 - 而不是取消狀態。
我同意 - 它適用於常見情況。有點奇怪的是,一個小孩'Task'(非'async')可能最終出錯(由於OperationCancelledException帶有錯誤的標記),但是這樣會導致父代('async')Task處於取消狀態。大多數情況下,我只是好奇並擔心bug的情況:意外的取消不會導致我的'async'代碼失敗,並且可能會延遲我注意到這個錯誤。 – 2013-03-06 21:43:07
有一些角落案件重新取消;例如,如果您將一個已經取消的標記傳遞給Task.Run,您將會得到一個取消的任務,在await時引發'TaskCanceledException',但是如果您取消了傳遞給Task.Run後的標記,任務開始,你會得到一個取消的任務,當await被引發時引發'OperationCanceledException'(* not *'TaskCanceledException')。無論如何,你不應該擔心錯誤,因爲你最終應該「等待」所有的任務(你關心的),任何被取消的任務將會在等待時拋出'OperationCanceledException'。 – 2013-03-06 21:54:45