问题关联起来的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