【发布时间】: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