【问题标题】:How exactly are timeouts handled by HttpClient?HttpClient 究竟是如何处理超时的?
【发布时间】:2015-04-24 15:27:08
【问题描述】:

因此可以在HttpClient 上设置两个超时属性:HttpClient.TimeOutWebRequestHandler.ReadWriteTimeout

第一个只是整个请求/响应的超时,所以如果下载/上传时间比这更长,我很不走运并且在传输过程中被切断,没有任何问题。这显然可以通过将超时设置为无限来覆盖,但我不确定这会产生什么后果。

现在后者 (ReadWriteTimeOut) - 至少在我的理解中 - 应该一直传播到 NetworkStream,它会影响请求/响应流在超时之前可以阻塞(空闲)多长时间。

HttpClient 正在使用 HttpWebRequest 方法的异步版本,但正如 here 所述:

在异步请求的情况下,客户端应用程序负责实现自己的超时机制。

根本没有解释他们想到的超时机制(网络流空闲超时?整个 HTTP GET 超时?等等),这让我非常困惑。

所以我的问题是,HttpClient 究竟如何处理网络/协议超时?我想使用 HttpClient 上传/下载潜在的大文件,因此我将 HttpClient.TimeOut 设置为无限。但我担心这样做会使应用程序面临无限等待服务器/网络拒绝完成的某些事件的风险。

【问题讨论】:

  • 您是否获得了有关这些超时的更多详细信息?
  • @SandeepKumar 除了我对下面“Leo Y”回答的 cmets 之外,我并没有真正了解更多细节。有太多的层需要反编译和通过。我建议使用反复试验来测试您感兴趣的超时情况。
  • 好的。还有一件事,如何使用 httpClient 对象获取 WebRequestHandler.ReadWriteTimeout?
  • @SandeepKumar 将WebRequestHandler 的实例传递给HttpClient 的构造函数。在你这样做之前,将WebRequestHandlerReadWriteTimeout 属性设置为任何你想要的。 This article 可能有助于解释一些事情。
  • 谢谢你,我学到了一些新东西:)

标签: c# .net http networking httpclient


【解决方案1】:

您的引用是针对 HttpWebRequest。但是,HttpClient.Timeout(仅在 .NET 4.5 中工作)适用于 HttpClient。因此,它在使用 HttpClient API 时处理超时。但是,将其设置为无限是一种不好的做法。在这种情况下,内部超时正在使用,这将导致大约 10 分钟后引发异常(如果内部超时值在 .NET 4.5 中未更改)

【讨论】:

  • 正如我所说,HttpClient 只是HttpWebRequest 的包装,所以引用是相关的。您能否详细说明那些“内部超时”?我发现您的陈述非常不透明,因为我最初的问题实际上是关于内部细节的。此外,在将.Timeout 设置为无限后,我可以轻松地将连接保持打开超过 20 分钟。
  • HttpClient 不是包装器,因为它与绑定到特定 URL 的 HttpWebRequest 相反,是独立于 URL 的。如果您在服务器端实现特定行为,则可以保持连接打开。例如 SSE(服务器发送事件)协议就利用了它。正如您所提到的,发出单个调用(例如调用 HttpClient.GetStringAsync())使用 HttpWebRequest 异步方法进行实现。我将检查 HttpClient.Timeout 的确切用法,并使用此信息更新答案。
  • 它是一个包装器,因为它只是将所有 HTTP 协议处理委托给 HttpWebRequest。您可以将它用于多个 URL 的事实是无关紧要的。 HttpClient.Timeout 几乎没用,因为它只是通过在请求开始时设置一个计时器来工作,如果整个异步操作(请求+响应)没有及时完成,它就会被取消。任何人都可以在最抽象的层用CancellationTokenSource + Task.Delay 实现的东西,所以它是无用的属性。问题是关于你提到的internal timeouts
  • 事实上它用作取消令牌的超时。现在,说了以上所有内容,您已经得到了有关“HttpClient 如何处理超时”的问题的答案。
  • 不,我不这样做:So my question is, how exactly does HttpClient handle network/protocol timeouts?。我还没有了解 HttpClient、HttpWebRequest、NetworkStream 和所有其他层的交互如何影响 HttpClient 中的最终超时机制。例如,将HttpClient.Timeout 设置为无限是否意味着HttpClient 永远不会超时?如果不是,那么 HttpClient 在什么情况下会超时?
【解决方案2】:

使用 HttpClient 下载文件时有 2 个选项

  1. 在您的 Get 请求中使用 HttpCompletionOption.ResponseContentRead(这是默认的隐式选项)。然后HttpClient.Timeout 有效地应用于整个下载过程。我想当您考虑无限超时时就是这种情况

  2. 在您的 Get 请求中明确使用 HttpCompletionOption.ResponseHeadersRead。然后HttpClient.Timeout 仅应用于获取没有内容的 Head 响应。 之后,您可以自行下载内容管理超时,例如response.Content.ReadAsStreamAsync()

我想选项 2 就是您想要的。只需设置一个HttpClient.Timeout 以在合理的时间内从服务器获得响应,然后下载内容

【讨论】:

    猜你喜欢
    • 2018-01-04
    • 2017-04-21
    • 1970-01-01
    • 2015-08-29
    • 1970-01-01
    • 1970-01-01
    • 2021-11-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多