简体   繁体   English

将 OperationCanceledException 与 CancellationToken 相关联的正确方法

[英]Proper way to correlate an OperationCanceledException to a CancellationToken

I'm using an async api which supports cancellation and I'm passing to that api a CancellationToken instance.我正在使用支持取消的异步 api,并且我正在向该 api 传递一个CancellationToken实例。 As usual, if the cancellation is requested on the passed token, the api that I'm invoking will throws an OperationCanceledException (this is the standard cooperative cancellation pattern of the .NET framework).像往常一样,如果在传递的令牌上请求取消,我正在调用的 api 将抛出OperationCanceledException (这是 .NET 框架的标准协作取消模式)。

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.当且仅当它是由于取消提供的取消令牌而引发的异常时,我希望能够捕获OperationCanceledException

The following code illustrates what I'm trying to achieve:以下代码说明了我要实现的目标:

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

For the exception filter of the code above I have basically two ideas:对于上面代码的异常过滤器我基本上有两个想法:

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

What is the right way to do the check I want to perform?进行我要执行的检查的正确方法是什么? Are the two ways showed above equivalent?上面显示的两种方式是否等效? Is there a best practice?有最佳实践吗?

IMPORTANT NOTE : I know that the code showed above can be written in a more efficient way, because catching exceptions is an expensive operation.重要提示:我知道上面显示的代码可以以更有效的方式编写,因为捕获异常是一项昂贵的操作。 The best thing to do is probably removing the first catch block at all, and only catching an Exception if and only if it is not related with the cancellation of the token object.最好的办法可能是完全删除第一个catch块,并且仅当且仅当它与token object 的取消无关时才捕获Exception I'm aware of that, but that's not the point of my question.我知道这一点,但这不是我问题的重点。 I have written the code in the question that way only for clarity , because the whole point of my question is how to properly correlate an OperationCanceledException with the CancellationToken which has caused the exception itself.我以这种方式编写问题中的代码只是为了清楚起见,因为我的问题的重点是如何正确地将OperationCanceledException与导致异常本身的CancellationToken相关联。

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.当且仅当它是由于取消提供的取消令牌而引发的异常时,我希望能够捕获 OperationCanceledException。

You can't do this exactly , but you can "catch the canceled exception only if my provided token has been cancelled", which is usually good enough.您不能完全做到这一点,但您可以“仅当我提供的令牌已被取消时才捕获已取消的异常”,这通常已经足够了。

when (token.IsCancellationRequested) is what you want. when (token.IsCancellationRequested)是你想要的。

Don't check the ex.CancellationToken , because the method you're calling may be observing a linked cancellation token, which would be different than the one you provided.不要检查ex.CancellationToken ,因为您调用的方法可能正在观察链接的取消令牌,这与您提供的不同。

暂无
暂无

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

相关问题 CancellationToken 不会导致 OperationCanceledException 被抛出 - CancellationToken not causing OperationCanceledException to be thrown 将 LINQ 与 CancellationToken 一起使用的正确方法 - Proper way to use LINQ with CancellationToken 从CancellationToken.Register内部抛出C#抛出OperationCanceledException - C# Throw OperationCanceledException from inside CancellationToken.Register 如果立即释放信号量,取消 SemaphoreSlim.WaitAsync(CancellationToken) 并不总是抛出 OperationCanceledException - Canceling a SemaphoreSlim.WaitAsync(CancellationToken) does not always throw OperationCanceledException if semaphore immediately released 使用 BlockingCollection<T> :OperationCanceledException,有没有更好的办法? - Using BlockingCollection<T>: OperationCanceledException, is there a better way? CancellationToken影响另一个CancellationToken控制的任务子集的好方法 - Good way for a CancellationToken to affect a subset of tasks controlled by another CancellationToken 有没有办法为所有动作为CancellationToken创建过滤器? - Is there a way to create a filter for CancellationToken for all actions? 取消不接受CancellationToken的异步操作的正确方法是什么? - What is the correct way to cancel an async operation that doesn't accept a CancellationToken? 以通用方式添加Handler方法以与xml中指定的Handler名称相关 - Adding Handler methods in a generic way to correlate to Handler names specified in an xml OperationCanceledException和TaskCanceledException之间的区别? - Difference between OperationCanceledException and TaskCanceledException?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM