C# 为什么在评估OperationCanceledException时检查cancelationToken?

C# 为什么在评估OperationCanceledException时检查cancelationToken?,c#,.net,azure-service-fabric,C#,.net,Azure Service Fabric,OperationCanceledException可能由于以下两种不同的原因引发: 已设置取消令牌,或 已超时(TaskCancelationException) 为了解决这个问题,一个常见的解决方法(在这里描述,等等:)如下: catch (OperationCanceledException ex) { if (token.IsCancellationRequested) { return -1; } return -2; } 但是,

OperationCanceledException可能由于以下两种不同的原因引发:

  • 已设置取消令牌,或
  • 已超时(TaskCancelationException)
为了解决这个问题,一个常见的解决方法(在这里描述,等等:)如下:

catch (OperationCanceledException ex)
{
    if (token.IsCancellationRequested)
    {
        return -1;
    }

    return -2;
}
但是,对于我来说,查看给予异常的实际取消状态更有意义。大概是这样的:

if (ex is OperationCanceledException ocEx)
{
    if (ocEx.CancellationToken.IsCancellationRequested)
    {
        return -1;
    }

    return -2;
}

我是否遗漏了一些内容,是否有一些原因导致此功能不能作为此常见问题的解决方案进行升级?

我一直使用
ex.CancellationToken.IsCancellationRequested
。这是标准的方法,阿福。在许多(如果不是大多数)情况下,您甚至无法访问
catch
块中的原始
token
变量。取消可能是由嵌套的token引起的,因此它实际上取决于正确的语义。检查传递给OCE的令牌的
IsCancellationRequested
,这有点愚蠢,因为OCE说“这是导致我的令牌,因此它被取消了”。您可能希望对照已知令牌检查OCE令牌,以确保它是由已知令牌抛出的:
if(One.CancellationToken==myCancellationToken)
-此处不检查“if cancelled”(因为如果OCE令牌是由CT触发的,则OCE令牌将被取消),而是检查它是否是相同的触发令牌。无论如何,语义..(提示:如果有一个内部CT导致OCE未与已知令牌链接,那么取消状态不会直接绑定到已知的
令牌
;因此是第一个语义。即使它是链接的,链接的令牌也可以独立取消,而不会触发链接源的取消,例如。)@user2864740我没有注意问题中关于超时的部分。在处理嵌套令牌或想要区分超时和取消请求时,您的逻辑实际上是有意义的。话虽如此,我100%确信我遇到过这样的情况,即抛出OCE但不涉及任何取消,此时
ex.CancellationToken.IsCancellationRequested
变得相关。@Hoppy如果您试图区分超时和取消请求,请注意,我的第一条评论不适用于这种情况,因为
ocEx.CancellationToken.IsCancellationRequested
在两种情况下都将返回true(您尝试过吗?),而
token.IsCancellationRequested
仅在取消的情况下返回true。