我试图将HttpClient调用的默认超时设置为5秒。
我已通过CancellationTokenSource
完成此操作。
这里是相关的代码:
var cancellationToken = new CancellationTokenSource();
cancellationToken.CancelAfter(TimeSpan.FromSeconds(5));
var result = _httpClient.SendAsync(request, cancellationToken.Token);
正如我预期的那样,调用代码获得"任务被取消"错误(我在.NET 4.7控制台应用程序中测试过),但我注意到在Fiddler中请求仍然运行了1分钟,直到它最终放弃:
有人可以解释这种行为吗?
我希望在触发取消时基础请求也会被取消。
_httpClient
实例化为:new HttpClient { BaseAddress = baseAddress }
我知道有Timeout
设置,但不确定我是否应该使用该设置或取消令牌?我的猜测Timeout
是非异步/等待情况吗?
答案 0 :(得分:2)
正如Damien在评论中所说,HttpClient
尽可能多地重新使用连接,因此取消时关闭的原因就不再是。
取消这样的请求时,HttpClient
将停止向/从另一端发送/接收数据。它不会发送任何信息通知另一方它被取消了。因此,您看到的1分钟超时取决于连接另一端的行为。
此外,如果您想在5秒后取消每个请求,也可以将Timeout
的{{1}}属性设置为_httpClient
。行为将完全相同(如果另一端在5秒内没有响应,则会抛出TimeSpan.FromSeconds(5)
。)
答案 1 :(得分:0)
如果有人感兴趣,您可以尝试以下方法来根据HttpClient
请求应用自己的超时。它似乎对我有用,将SendAsync()
限制为2秒,并在发生超时时立即返回:
private async Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request,
TimeSpan? timeout = null)
{
if (timeout == null)
return await _httpClient.SendAsync(request);
else
{
using (var cts = new CancellationTokenSource(timeout.Value))
{
var sendTask = _httpClient.SendAsync(request);
while (true)
{
if (sendTask.IsCompleted)
break;
else
{
cts.Token.ThrowIfCancellationRequested();
Thread.Sleep(10);
}
}
return await sendTask;
}
}
}