C# System.Net.WebException:操作已超时
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1215488/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
System.Net.WebException: The operation has timed out
提问by
I have a big problem: I need to send 200 objects at once and avoid timeouts.
我有一个大问题:我需要一次发送 200 个对象并避免超时。
while (true)
{
NameValueCollection data = new NameValueCollection();
data.Add("mode", nat);
using (var client = new WebClient())
{
byte[] response = client.UploadValues(serverA, data);
responseData = Encoding.ASCII.GetString(response);
string[] split = Javab.Split(new[] { '!' }, StringSplitOptions.RemoveEmptyEntries);
string command = split[0];
string server = split[1];
string requestCountStr = split[2];
switch (command)
{
case "check":
int requestCount = Convert.ToInt32(requestCountStr);
for (int i = 0; i < requestCount; i++)
{
Uri myUri = new Uri(server);
WebRequest request = WebRequest.Create(myUri);
request.Timeout = 200000;
WebResponse myWebResponse = request.GetResponse();
}
break;
}
}
}
This produces the error:
这会产生错误:
Unhandled Exception: System.Net.WebException: The operation has timed out
at System.Net.HttpWebRequest.GetResponse()
at vir_fu.Program.Main(String[] args)
The requestCount
loop works fine outside my base code but when I add it to my project I get this error. I have tried setting request.Timeout = 200;
but it didn't help.
该requestCount
循环在我的基本代码之外工作正常,但是当我将它添加到我的项目时,我收到此错误。我试过设置,request.Timeout = 200;
但没有帮助。
回答by Freddy
I remember I had the same problem a while back using WCF due the quantity of the data I was passing. I remember I changed timeouts everywhere but the problem persisted. What I finally did was open the connection as stream request, I needed to change the client and the server side, but it work that way. Since it was a stream connection, the server kept reading until the stream ended.
我记得由于我传递的数据量,我在使用 WCF 时遇到了同样的问题。我记得我到处都更改了超时,但问题仍然存在。我最终做的是将连接作为流请求打开,我需要更改客户端和服务器端,但它以这种方式工作。由于是流连接,服务器一直读取直到流结束。
回答by John Saunders
It means what it says. The operation took too long to complete.
这意味着它所说的。该操作花费了很长时间才能完成。
BTW, look at WebRequest.Timeoutand you'll see that you've set your timeout for 1/5 second.
顺便说一句,看看WebRequest.Timeout,您会看到您已将超时设置为 1/5 秒。
回答by Matt Brindley
I'm not sure about your first code sample where you use WebClient.UploadValues, it's not really enough to go on, could you paste more of your surrounding code? Regarding your WebRequest code, there are two things at play here:
我不确定您使用 WebClient.UploadValues 的第一个代码示例,这还不够继续,您能否粘贴更多周围的代码?关于您的 WebRequest 代码,这里有两件事在起作用:
You're only requesting the headers of the response**, you never read the body of the response by opening and reading (to its end) the ResponseStream. Because of this, the WebRequest client helpfully leaves the connection open, expecting you to request the body at any moment. Until you either read the response body to completion (which will automatically close the stream for you), clean up and close the stream (or the WebRequest instance) or wait for the GC to do its thing, your connection will remain open.
You have a default maximum amount of activeconnections to the same host of 2. This means you use up your first two connections and then never dispose of them so your client isn't given the chance to complete the next request before it reaches its timeout (which is milliseconds, btw, so you've set it to 0.2 seconds - the default should be fine).
您只是请求响应的标头**,您永远不会通过打开和读取(到其末尾)ResponseStream 来读取响应的正文。因此,WebRequest 客户端有助于保持连接打开,期待您随时请求正文。直到您读取响应正文完成(这将自动为您关闭流)、清理并关闭流(或 WebRequest 实例)或等待 GC 执行其操作,您的连接将保持打开状态。
您与同一主机的默认最大活动连接数为 2。这意味着您用完前两个连接,然后永远不会处理它们,因此您的客户端没有机会在下一个请求超时之前完成它(顺便说一句,这是毫秒,所以您已将其设置为 0.2 秒 - 默认值应该没问题)。
If you don't want the body of the response (or you've just uploaded or POSTed something and aren't expecting a response), simply close the stream, or the client, which will close the stream for you.
如果您不想要响应的正文(或者您刚刚上传或发布了某些内容并且不希望收到响应),只需关闭流或客户端,这将为您关闭流。
The easiest way to fix this is to make sure you use using blocks on disposable objects:
解决此问题的最简单方法是确保在一次性对象上使用 using 块:
for (int i = 0; i < ops1; i++)
{
Uri myUri = new Uri(site);
WebRequest myWebRequest = WebRequest.Create(myUri);
//myWebRequest.Timeout = 200;
using (WebResponse myWebResponse = myWebRequest.GetResponse())
{
// Do what you want with myWebResponse.Headers.
} // Your response will be disposed of here
}
Another solution is to allow 200 concurrent connections to the same host. However, unless you're planning to multi-thread this operation so you'd need multiple, concurrent connections, this won't really help you:
另一种解决方案是允许 200 个并发连接到同一主机。但是,除非您打算多线程执行此操作,因此您需要多个并发连接,否则这不会真正帮助您:
ServicePointManager.DefaultConnectionLimit = 200;
When you're getting timeouts within code, the best thing to do is try to recreate that timeout outside of your code. If you can't, the problem probably lies with your code. I usually use cURLfor that, or just a web browser if it's a simple GET request.
当您在代码中遇到超时时,最好的办法是尝试在您的代码之外重新创建该超时。如果你不能,问题可能出在你的代码上。我通常为此使用cURL,或者如果它是一个简单的 GET 请求,则只使用Web 浏览器。
** In reality, you're actually requesting the first chunk of data from the response, which contains the HTTP headers, and also the start of the body. This is why it's possible to read HTTP header info (such as Content-Encoding, Set-Cookie etc) before reading from the output stream. As you read the stream, further data is retrieved from the server. WebRequest's connection to the server is kept open until you reach the end of this stream (effectively closing it as it's not seekable), manually close it yourself or it is disposed of. There's more about this here.
** 实际上,您实际上是从响应中请求第一块数据,其中包含 HTTP 标头以及正文的开头。这就是为什么可以在从输出流中读取之前读取 HTTP 标头信息(例如 Content-Encoding、Set-Cookie 等)的原因。当您读取流时,会从服务器检索更多数据。WebRequest 与服务器的连接保持打开状态,直到您到达此流的末尾(有效地将其关闭,因为它不可搜索)、您自己手动关闭它或将其丢弃。这里有更多关于这个的信息。
回答by Joe Chung
Close/dispose your WebResponse object.
关闭/处置您的 WebResponse 对象。
回答by Blue Clouds
proxy issue can cause this. IIS webconfig put this in
代理问题可能会导致这种情况。IIS webconfig 把这个放进去
<defaultProxy useDefaultCredentials="true" enabled="true">
<proxy usesystemdefault="True" />
</defaultProxy>