【问题标题】:HttpClient - two timeouts for large uploadsHttpClient - 大型上传的两次超时
【发布时间】:2026-01-18 01:35:01
【问题描述】:

我正在使用 .net HttpClient,但这可能是关于 HTTP 的更普遍的问题: 我希望允许用户通过有时缓慢且不可靠的移动连接上传大文件。 如果在 20 秒内没有开始上传,则可能存在连接问题,因此应用程序应采取适当的措施(例如,暂时放弃,稍后再试。) 但如果开始上传,可能需要几分钟才能完成。在这种情况下,我不希望超时来中断它。然后我只想在上传进度慢到爬行时放弃并抛出错误。

所以我似乎想要两个超时条件 - 初始连接超时 20 秒,上传完成超时 10 分钟(或最好是动态计算)。

有没有办法做到这一点? HttpClient.Timeout 似乎对整个上传设置了限制,而不仅仅是初始连接。

我正在使用 HttpClient.PutAsync(),并通过覆盖 HttpContent.SerializeToStreamAsync() 来监控进度。如有必要,我可以在此函数中包含一个最低速度检查,以在进度太慢时终止。

干杯。

【问题讨论】:

    标签: http upload timeout dotnet-httpclient


    【解决方案1】:

    HttpClient 的超时对您没有用处。据我所知,没有办法区分连接时间范围和发送请求正文。

    您最好的选择是按照您的建议创建自己的派生 HttpContent,或者使用 PushStreamContent。这将允许您监控发送进度。

    假设您的服务器不返回 connection:close 您可以使用打开 TCP 连接的 HEAD 请求来访问服务器,然后您的第二个请求可以是 PUT,它将重新使用 TCP 连接。至少这样您就知道服务器可用。

    【讨论】:

    • 但是,由于某些未知原因,PutAsync 重载都没有采用 HttpCompletionOption。这是否意味着我需要使用 SendAsync 代替?我该怎么做?我找不到使用 HttpClient 方法的示例。
    • 那么在上面的代码中,我该如何使用响应变量来执行实际的上传? (带有进度报告)。我在 WebRequest 或 HttpClient.PutAsync 中使用的方法似乎不适用于这种情况。
    • @thund 我添加了一个更新,希望这足以让你继续前进。
    • 但是 response.Content 是一个 HttpContent,它没有 GetStreamAsync()。它有一个 ReadAsStreamAsync(),但它提供了一个不可写的流,所以我不能用它来上传任何东西。
    • @thund 哦,很抱歉混淆了这个问题。我完全错过了您关于上传大文件的观点。我会更新我的答案。