将 OperationCanceledException 关联到 CancellationToken 的正确方法

Proper way to correlate an OperationCanceledException to a CancellationToken

我正在使用支持取消的异步 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;
}

对于上面代码的异常过滤器,我基本上有两个想法:

进行我想要执行的检查的正确方法是什么?上面显示的两种方式是否等效?有最佳实践吗?

重要提示:我知道上面显示的代码可以用更有效的方式编写,因为捕获异常是一项昂贵的操作。最好的办法可能是完全删除第一个 catch 块,并且仅当且仅当它与 token 对象的取消无关时才捕获 Exception 。我知道这一点,但这不是我问题的重点。 我只是为了清楚起见才以这种方式编写问题中的代码,因为我的问题的重点是如何正确地将 OperationCanceledExceptionCancellationToken 相关联导致异常本身。

I want to be able to catch the OperationCanceledException if and only if it is the exception raised due to the cancellation of the provided cancellation token.

你不能完全,但你可以“仅在我提供的令牌已被取消时捕获已取消的异常”,这通常就足够了。

when (token.IsCancellationRequested)就是你想要的。

不要检查 ex.CancellationToken,因为您调用的方法可能正在观察链接的取消令牌,这与您提供的不同。