繁体   English   中英

将 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;
}

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

  • 检查token object 上的IsCancellationRequested属性: when (token.IsCancellationRequested)
  • 检查ex object 上的CancellationToken属性: when (ex.CancellationToken == token)

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

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

当且仅当它是由于取消提供的取消令牌而引发的异常时,我希望能够捕获 OperationCanceledException。

您不能完全做到这一点,但您可以“仅当我提供的令牌已被取消时才捕获已取消的异常”,这通常已经足够了。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM