3

现在的情况

有一个客户端通过 HttpClient.GetAsync 执行获取请求。不幸的是,出于某种原因,我们需要阻止这些调用。

为此,使用此 Asynchelper 类以避免上下文切换死锁(而不仅仅是使用 .Result)

   public static class AsyncHelper
   {
       private static readonly TaskFactory _myTaskFactory = new
             TaskFactory(CancellationToken.None,
                         TaskCreationOptions.None,
                         TaskContinuationOptions.None,
                         TaskScheduler.Default);


    public static void RunSync(Func<Task> func)
    {
        AsyncHelper._myTaskFactory
          .StartNew<Task>(func)
          .Unwrap()
          .GetAwaiter()
          .GetResult();
    }
}

然后实际的调用如下所示:

AsyncHelper.RunSync(Async Function() Await _httpClient.GetAsync(uri, HttpCompletionOption.ResponseHeadersRead))

问题

在使用 Netlimiter 降低网络速度的压力测试期间,我们遇到了请求未完成的问题。例如,当我终止网络连接(在 NetLimiter 中)时,这样的请求将永远留在客户端。它将停留在 AsyncHelper.RunSync 调用中,直到遇到 httpClient.Timeout。

当连接丢失时,不应该有一个异常会结束这个调用吗?我错过了什么吗?

4

1 回答 1

3

问题是 HTTP 连接通常通过 TCP 连接进行。因此,当您强制终止 TCP 连接而无法发送其“我在这里完成”(或 FIN)数据包时,连接的另一端仍然乐于等待更多数据,至少直到某个定义的超时可以在套接字查询操作中从上面配置。

处理此问题的一种方法是在套接字上设置TCP Keep-Alive 。请注意,这与HTTP Keep-Alive非常不同。另一种选择是,就像已经发生的那样,使用足够好的超时。

于 2016-01-28T16:40:42.277 回答