为什么HttpWebRequest即使在传输过程中也会超时?

时间:2022-09-19 03:41:20

We have the same error as Alexander Sun in his question at MSDN where an upload is aborted when it takes longer than the time specified in HttpWebRequest.Timeout -- which is kind of unexpected. We think similar to gouravmukherjee who writes in the forum:

我们在MSDN的问题中遇到与Alexander Sun相同的错误,当上传时间超过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.

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

He also goes further in a later post:

他还在后来的帖子中进一步说:

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.

我和MS谈到了这件事,并被告知如果上传时间太长,这个超时应该会让线程不再挂起。 .net显然不关心套接字上的活动,只关心超时。这就是上传文件突然停止的原因。

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

我觉得这是一个框架不关心socket上的活动的bug,你怎么看?

Our test code is very simple:

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

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();

This results in the following exception:

这导致以下异常:

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

Interestingly the error does only happen with the Microsoft Runtime. When using Mono everything works as expected: While writing to the stream, the timeout measurement is stopped.

有趣的是,错误只发生在Microsoft Runtime上。使用Mono时,一切都按预期工作:写入流时,停止超时测量。

We wonder how to work around this problem on the Microsoft Runtime. Is it ok to set Timeout to infinity? We feel that this is not a good option. Or is there no other way than to switch to a asynchronous implementation. Since we run on a separate thread anyway, we would prefer the simple synchronous API.

我们想知道如何解决Microsoft Runtime上的这个问题。可以将Timeout设置为无穷大吗?我们觉得这不是一个好选择。或者没有其他方法可以切换到异步实现。由于我们无论如何都在单独的线程上运行,我们更喜欢简单的同步API。

2 个解决方案

#1


4  

An update, since this question has been open a long time. We never found an answer to the original question (why the timeout is occurring). We feel that this is a bug in the Microsoft Runtime.

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

We found no other way to solve the timeout issue than to switch to the asynchronous API of HttpWebRequest, and implement the timeout mechanism ourselves. The custom timeout is only applied when waiting for the BeginGetRequestStream and BeginGetResponse methods to finish. The timeout is not applied when doing the actual upload or download. Our timeout implementation is based on this MSDN example code: http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.abort(v=vs.110).aspx.

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

#2


0  

One thing you should look at is the .ReadWriteTimout, try setting that value to see if you get the results you are wanting.

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

Cheers!

干杯!

#1


4  

An update, since this question has been open a long time. We never found an answer to the original question (why the timeout is occurring). We feel that this is a bug in the Microsoft Runtime.

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

We found no other way to solve the timeout issue than to switch to the asynchronous API of HttpWebRequest, and implement the timeout mechanism ourselves. The custom timeout is only applied when waiting for the BeginGetRequestStream and BeginGetResponse methods to finish. The timeout is not applied when doing the actual upload or download. Our timeout implementation is based on this MSDN example code: http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.abort(v=vs.110).aspx.

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

#2


0  

One thing you should look at is the .ReadWriteTimout, try setting that value to see if you get the results you are wanting.

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

Cheers!

干杯!