Skip to main content
 首页 » 编程设计

c#之为什么即使传输正在进行,HttpWebRequest 也会超时

2024年02月13日28qlqwjy

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

What I am trying to say is that the .net framework seems to close the connection after the default timeout period. I am not saying that I need to change this timeout, my point is why should the request be timed out or cancelled at all when the client is still sending data. I can understand that a timeout may happen when the connection is idle, but if there is data transfer going on, it should not be stopped forcibly.

他还在后面的帖子中走得更远:

I spoke to MS about this and was told that this timeout is supposed keep the thread from hanging if the upload took too long. .net apparently does not care for the activity on the socket and cares only for the timeout. This is why uploading the the file stops abruptly.

I feel this is a bug that the framework doesn't care for activity on the socket, what do you think?

我们的测试代码非常简单:

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。

请您参考如下方法:

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

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