Eug*_*sky 26 .net c# timeout task-parallel-library dotnet-httpclient
HttpClient有一个内置超时功能(尽管都是异步的,即超时可以被认为是与http请求功能正交,因此可以由通用异步实用程序处理,但是除此之外)当超时启动时,它会抛出一个TaskCanceledException(包含在内) a AggregateException).
TCE包含CancellationToken等于的CancellationToken.None.
现在,如果我提供HttpClient了CancellationToken我自己的一个并使用它来取消操作完成(或超时),我得到完全相同TaskCanceledException,再次使用CancellationToken.None.
通过仅查看抛出的异常,还有一种方法可以确定超时是否取消了请求,而不必让我自己CancellationToken可以访问检查异常的代码?
PS这可能是一个错误,并CancellationToken以某种方式错误地修复CancellationToken.None?在取消使用自定义CancellationToken的情况下,我希望TaskCanceledException.CancellationToken等于该自定义令牌.
编辑
为了使问题更加清晰,通过访问原始文件CancellationTokenSource,很容易区分超时和用户取消:
origCancellationTokenSource.IsCancellationRequested == true
CancellationToken从异常中获取但是给出了错误的答案:
((TaskCanceledException)e.InnerException).CancellationToken.IsCancellationRequested == false
这是一个最小的例子,由于受欢迎的需求:
public void foo()
{
makeRequest().ContinueWith(task =>
{
try
{
var result = task.Result;
// do something with the result;
}
catch (Exception e)
{
TaskCanceledException innerException = e.InnerException as TaskCanceledException;
bool timedOut = innerException != null && innerException.CancellationToken.IsCancellationRequested == false;
// Unfortunately, the above .IsCancellationRequested
// is always false, no matter if the request was
// cancelled using CancellationTaskSource.Cancel()
// or if it timed out
}
});
}
public Task<HttpResponseMessage> makeRequest()
{
var cts = new CancellationTokenSource();
HttpClient client = new HttpClient() { Timeout = TimeSpan.FromSeconds(10) };
HttpRequestMessage httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, "url");
passCancellationTokenToOtherPartOfTheCode(cts);
return client.SendAsync(httpRequestMessage, cts.Token);
}
Run Code Online (Sandbox Code Playgroud)
是的,它们都返回相同的异常(可能是因为内部使用令牌的超时),但通过这样做可以很容易地找出它:
catch (OperationCanceledException ex)
{
if (token.IsCancellationRequested)
{
return -1;
}
return -2;
}
Run Code Online (Sandbox Code Playgroud)
所以基本上如果你遇到异常但你的令牌没有被取消,那么这是一个常规的http超时
接受的答案肯定是理论上应该如何工作,但不幸的是,在实践中IsCancellationRequested并没有(可靠地)设置附加到异常的令牌:
取消HttpClient请求 - 为什么TaskCanceledException.CancellationToken.IsCancellationRequested为false?
| 归档时间: |
|
| 查看次数: |
7568 次 |
| 最近记录: |