【问题标题】:C# HttpClient server timeout cancels all subsequent requestsC# HttpClient 服务器超时取消所有后续请求
【发布时间】:2017-07-15 01:17:16
【问题描述】:

我已按照示例 herehere 使用 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


【解决方案1】:

CreateLinkedTokenSource 创建一个 CancellationTokenSource,当任何源令牌处于取消状态时,该 CancellationTokenSource 将处于取消状态。

所以我猜这是问题所在,每次只创建新的令牌源,不要将其链接到任何东西:

try
{
    var cs = new CancellationTokenSource();
    // ...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    • 2020-03-10
    • 1970-01-01
    • 2019-02-18
    相关资源
    最近更新 更多