【发布时间】:2017-07-15 01:17:16
【问题描述】:
我已按照示例 here 和 here 使用 C# HttpClient 成功处理超时,但我无法使其正常工作!
var urls = new List<string> { "/success", "/willtimeout", "/success" };
var baseAddress = "http://endpoint";
var httpClient = new HttpClient();
httpClient.Timeout = new TimeSpan(0, 0, 30);
httpClient.BaseAddress = new Uri(baseAddress);
foreach (var url in urls)
{
try
{
var cs = CancellationTokenSource.CreateLinkedTokenSource(CancellationToken.None);
cs.CancelAfter(new TimeSpan(0, 0, 3));
var result = await httpClient.GetAsync(urls, cs.Token);
Console.WriteLine("Success");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
这段代码会打印出来
Success
A task was canceled.
A task was canceled.
如何在不每次都创建新的 HttpClient 的情况下使其正常工作?
【问题讨论】:
-
我无法产生相同的结果,尽管我没有您的端点。端点是否响应第三次调用?
-
@dkackman 经过对一些 WireShark 数据包嗅探的更多调查,如果我重新使用 httpClient,SYN/ACK 不会在第二次调用时发送到服务器。第 2 次调用超时,httpClient 为第 3 次调用发送 SYN/ACK,但服务器没有应答,这会造成超时。当我不重新使用 httpClient 时,它会为每个请求发送一个 SYN/ACK,不会发生任何问题。所以这似乎是服务器问题?令人惊讶的是,这是由 IIS7.5 服务器提供的,这让我相信这将是一个代码问题......但我真的想知道如何对这种锁进行编码。
-
无论 "/willtimeout" 做什么,如果它使整个服务无响应,它听起来确实是一个数字。这是您控制的服务还是其他人的代码?
-
不,我无法控制它。我曾尝试为 /willtimeout 创建一个具有无限 Task.Delay 的服务器,但我无法重现目标服务器正在执行的确切行为。我也试过连接关闭。它没有用。我必须解决这个问题,并为每个飞行请求使用一个 HttpClient。如果请求不再处于运行状态,我可以重新使用它。如果请求超时,我将 HttpClient 扔掉。
标签: c# httpclient dotnet-httpclient