区分超时与用户取消

时间:2012-10-01 02:37:01

标签: c# .net timeout task-parallel-library dotnet-httpclient

HttpClient具有内置超时功能(尽管全部是异步的,即超时可以被视为与http请求功能正交,因此可以由通用异步实用程序处理,但除此之外)并且当超时启动时,它会抛出TaskCanceledException(包裹在AggregateException中)。

TCE包含等于CancellationToken的{​​{1}}。

现在,如果我向CancellationToken.None提供我自己的HttpClient,并在完成(或超时)之前使用该操作取消操作,我会再次得到完全相同的CancellationToken使用TaskCanceledException

还有一种方法,仅查看抛出的异常,以确定超时是否取消了请求,而无需让我自己的CancellationToken.None可访问代码检查异常?

P.S。这可能是一个错误而CancellationToken错误地修复了CancellationToken吗?在取消使用自定义CancellationToken 的情况下,我希望CancellationToken.None等于该自定义令牌。

修改 为了使问题更加清晰,通过访问原始TaskCanceledException.CancellationToken,很容易区分超时和用户取消:

  

origCancellationTokenSource.IsCancellationRequested == true

从异常中获取CancellationTokenSource会给出错误的答案:

  

((TaskCanceledException)e.InnerException).CancellationToken.IsCancellationRequested == false

此处最小示例,由于受欢迎的需求:

CancellationToken

2 个答案:

答案 0 :(得分:5)

是的,它们都返回相同的异常(可能是因为内部使用令牌的超时),但可以通过这样做很容易理解:

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

                return -2;
            }

所以基本上如果你遇到了异常,但你的令牌没有被取消,那么这是一个常规的http超时

答案 1 :(得分:5)

接受的答案肯定是应该在理论上如何工作,但不幸的是,在实践中IsCancellationRequested没有(可靠地)设置在附加到异常的令牌上:

Cancelling an HttpClient Request - Why is TaskCanceledException.CancellationToken.IsCancellationRequested false?