【发布时间】:2021-04-21 21:36:27
【问题描述】:
我正在使用一个支持取消的异步 api,并且我正在向该 api 传递一个 CancellationToken 实例。像往常一样,如果在传递的令牌上请求取消,我正在调用的 api 将抛出 OperationCanceledException(这是 .NET 框架的标准协作取消模式)。
我希望能够捕获OperationCanceledException当且仅当它是由于取消提供的取消令牌而引发的异常。
以下代码说明了我想要实现的目标:
try
{
await _service.DoSomethingAsync(cancellationToken: token);
}
catch (OperationCanceledException ex) when ( /* here I want a condition signifying that the OperationCanceledException is caused by the cancellation of the token object */)
{
// avoid logging the exception: this is raised by design (cooperative cancellation)
throw;
}
catch (Exception ex)
{
_logger.LogError(ex, "An error occurred: {0}", ex.Message);
throw;
}
对于上面代码的异常过滤,我基本上有两个想法:
- 检查
token对象上的IsCancellationRequested属性:when (token.IsCancellationRequested) - 检查
ex对象上的CancellationToken属性:when (ex.CancellationToken == token)
进行我要执行的检查的正确方法是什么?上面显示的两种方式是否等效?有最佳做法吗?
重要提示:我知道上面显示的代码可以用更有效的方式编写,因为捕获异常是一项昂贵的操作。最好的办法可能是完全删除第一个catch 块,并且仅当且仅当它与取消token 对象无关时才捕获Exception。我知道这一点,但这不是我问题的重点。 为了清楚起见,我以这种方式编写了问题中的代码,因为我的问题的重点是如何正确地将 OperationCanceledException 与导致异常本身的 CancellationToken 相关联。
【问题讨论】:
-
前者更有意义,因为两个令牌都可能被取消
标签: c# .net-core async-await cancellation cancellation-token