问题:是否有办法将CancellationToken与从async方法返回的任务(Task)相关联?
通常情况下,如果使用与任务(Task)的CancellationToken匹配的CancellationToken抛出OperationCancelledException,则任务(Task)将最终处于Canceled状态。如果它们不匹配,则任务(Task)进入Faulted状态。
通常情况下,如果使用与任务(Task)的CancellationToken匹配的CancellationToken抛出OperationCancelledException,则任务(Task)将最终处于Canceled状态。如果它们不匹配,则任务(Task)进入Faulted状态。
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
状态,而不是Canceled
状态。因此,希望能够有更多的控制。
Task
(非async
)可能会因为使用错误的令牌(OperationCancelledException
)而失败,但这会导致父(async
)Task
处于取消状态。主要是我只是好奇并担心出现错误的情况:意外的取消不会导致我的async
代码失败,也许会延迟我发现错误。 - Matt SmithTask.Run
,你会得到一个被取消的任务,在await
时会引发TaskCanceledException
,但是如果你在任务开始后取消传递给Task.Run
的令牌,你会得到一个被取消的任务,在await
时会引发OperationCanceledException
(不是TaskCanceledException
)。无论如何,你不必担心错误,因为你最终应该await
所有任务(你关心的),任何被取消的任务在await
时都会抛出OperationCanceledException
。 - Stephen Cleary