3

我试图为我的HttpClient调用设置一个默认的超时时间为5秒。HttpClient取消不杀死底层的TCP通话

我已通过CancellationTokenSource完成了此操作。

这里的代码的相关位:

var cancellationToken = new CancellationTokenSource(); 
cancellationToken.CancelAfter(TimeSpan.FromSeconds(5)); 
var result = _httpClient.SendAsync(request, cancellationToken.Token); 

工程,我预计在调用代码得到一个方面“任务被取消”的错误(我在.NET 4.7的控制台应用程序进行测试),但我在提琴手注意到请求仍在运行1分钟,直到它最终还是放弃了:

enter image description here

有人能解释这种现象?

我希望在取消触发时,底层请求也会被取消。

_httpClient被实例化,如:new HttpClient { BaseAddress = baseAddress }

我知道有在该Timeout设置,但不知道我是否应该使用或取消标记?我的猜测是Timeout是针对非异步/等待的情况?

+3

HTTP 1.1中没有“取消此请求”操作,除了拆除整个连接外 - 我猜测HttpClient不支持Keepalive /连接重用。 –

+0

@Damien_The_Unbeliever啊......当然......完全忘了'Keep-Alive'。顺便说一句,你可以在HTTP客户端中将Keep-Alive设置为false(默认值为true,因为很好理由) – RPM1984

+1

@Damien_The_Unbeliever,但是已经说过 - 如果我们不能取消底层的_request_(不是连接,而是_request_)那么取消令牌的意义何在?只是让客户端(浏览器,或在我的示例控制台应用程序)不关心结果了? (但请求可能仍然在后台运行) – RPM1984

回答

1

正如Damien在评论中所说的,HttpClient尽可能地重新使用了连接,因此连接在取消时没有关闭。

当取消这样的请求时,HttpClient将停止向/从另一端发送/接收数据。它不会发送任何信息通知对方它已被取消。因此,您看到1分钟的超时取决于连接另一端的行为。

另外,如果您想在5秒后取消每个请求,您还可以将_httpClientTimeout属性设置为TimeSpan.FromSeconds(5)。行为将完全相同(如果另一端在5秒内没有响应,则会引发TaskCanceledException)。