C# 将CancellationToken与异步方法关联';的任务
问题:是否有方法将C# 将CancellationToken与异步方法关联';的任务,c#,task-parallel-library,async-await,C#,Task Parallel Library,Async Await,问题:是否有方法将CancellationToken与从async方法返回的任务关联 通常,如果使用与任务的取消标记匹配的取消标记抛出操作取消异常,则任务将以取消状态结束。如果它们不匹配,则任务进入故障状态: void WrongCancellationTokenCausesFault() { var cts1 = new CancellationTokenSource(); var cts2 = new CancellationTokenSour
CancellationToken
与从async
方法返回的任务关联
通常,如果使用与任务的取消标记匹配的取消标记抛出操作取消异常,则任务将以取消状态结束。如果它们不匹配,则任务进入故障状态:
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
,我还没有找到一种方法来设置方法的任务的取消令牌(从而实现相同的功能)。根据我的测试,似乎任何操作取消异常
都会导致异步
方法进入取消状态:
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
方法中捕获OperationCanceledException
,并抛出符合所需语义的异常。如果您想重复使用这些语义,那么Task
的扩展方法应该符合要求。。有点奇怪的是,子任务
(非异步
)最终可能会出现故障(由于操作取消异常
具有错误的令牌),但这将导致父(异步
)任务处于取消状态。大多数时候,我只是好奇和担心这个bug:一个意外的取消不会导致我的async
代码失败,也许会延迟我注意到这个bug;e、 例如,如果您将已取消的令牌传递给Task.Run
,则当wait
ed时,您将获得引发TaskCanceledException
的已取消任务,但如果您取消传递给Task.Run
的令牌,则在任务启动后,您将获得引发OperationCanceledException
(不是TaskCanceledException
)当wait
ed时。无论如何,你不必担心bug,因为你最终应该wait
所有任务(你关心的),任何被取消的任务都会在wait
ed时抛出OperationCanceledException
。