【问题标题】:Why does HttpWebRequest time out even when transfer is ongoing?为什么即使传输正在进行,HttpWebRequest 也会超时?
【发布时间】:2013-12-15 14:37:30
【问题描述】:

我们遇到与Alexander Sun in his question at MSDN 相同的错误,当上传时间超过 HttpWebRequest.Timeout 中指定的时间时,上传被中止——这有点出乎意料。我们的想法类似于在论坛中写道的 gouravmukherjee:

我想说的是,.net 框架似乎在默认超时期限后关闭了连接。我并不是说我需要更改这个超时时间,我的观点是当客户端仍在发送数据时,为什么要超时或取消请求。我可以理解连接空闲时可能会发生超时,但是如果正在进行数据传输,则不应强行停止。

他还在后面的帖子中更进一步:

我就此与 MS 进行了交谈,并被告知如果上传时间过长,此超时应该可以防止线程挂起。 .net 显然不关心套接字上的活动,只关心超时。这就是上传文件突然停止的原因。

我觉得这是一个框架不关心套接字上的活动的错误,你怎么看?

我们的测试代码很简单:

string uri = "http://192.168.2.4:8080";
HttpWebRequest request = HttpWebRequest.CreateDefault(new Uri(uri)) as HttpWebRequest;
request.Method = "POST";
var bytes = Encoding.UTF8.GetBytes("Test content\n");
int repeat = 500000; // upload much data to take longer than request.Timeout
request.ContentLength = bytes.Length * repeat;
request.Timeout = 1000; // 1 second
var stream = request.GetRequestStream();
for (int i = 0; i < repeat; ++i)
    stream.Write(bytes, 0, bytes.Length); //exception is thrown here
stream.Close();
var response = request.GetResponse();

这会导致以下异常:

Unhandled Exception: System.Net.WebException: The request was aborted: The request was canceled.
    at System.Net.ConnectStream.InternalWrite(Boolean async, Byte[] buffer, Int32 offset, Int32 size, AsyncCallback callback, Object state)
    at System.Net.ConnectStream.Write(Byte[] buffer, Int32 offset, Int32 size)
    at httptest.MainClass.Main(String[] args) in c:\Users\work\Desktop\httptest\httptest\Program.cs:line 27

有趣的是,该错误仅发生在 Microsoft 运行时。使用 Mono 时一切正常:写入流时,超时测量停止。

我们想知道如何在 Microsoft 运行时解决此问题。可以将超时设置为无穷大吗?我们认为这不是一个好的选择。或者除了切换到异步实现之外别无他法。因为无论如何我们都在单独的线程上运行,所以我们更喜欢简单的同步 API。

【问题讨论】:

  • 你说得好像没有其他选项超时持续时间比 1 秒或无穷大。中间肯定有什么东西吗?
  • 1秒的超时只是为了测试行为。当然,我们会为生产代码设置更高的超时时间。我们不想做的是在超时中考虑上传时间。在互联网连接速度较慢的情况下,上传较大的文件可能需要很长时间。另一方面,我想为最后的request.GetResponse()call 设置一个短暂的超时时间。

标签: c# .net upload timeout httpwebrequest


【解决方案1】:

更新,因为这个问题已经开放了很长时间。我们从未找到原始问题的答案(为什么会发生超时)。我们认为这是 Microsoft Runtime 中的一个错误。

我们没有找到解决超时问题的方法,只能切换到HttpWebRequest的异步API,自己实现超时机制。自定义超时仅在等待 BeginGetRequestStreamBeginGetResponse 方法完成时应用。执行实际上传或下载时不应用超时。我们的超时实现基于此 MSDN 示例代码:http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.abort(v=vs.110).aspx

【讨论】:

    【解决方案2】:

    您应该查看的一件事是 .ReadWriteTimout,尝试设置该值以查看您是否获得了想要的结果。

    干杯!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-05
      • 2023-03-27
      • 2020-10-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多