HttpWebRequest 在第二次调用时超时
为什么以下代码在第二次(及后续)运行时超时?
代码挂在:
using (Stream objStream = request.GetResponse().GetResponseStream())
然后导致 WebException 表明请求已超时。
我已经用 WebRequest
和 HttpWebRequest
尝试过
编辑:代码似乎在 request.GetResponse()
中失败了
编辑:这篇文章建议可能是 GC 问题 --> http://www.vbforums.com/showthread.php?t=610043 - 根据这篇文章,如果 Fiddler 在后台打开,问题就会得到缓解。
服务器就在那里并且可以处理请求。
private string GetQLMResponse(string URL)
{
HttpWebRequest request = WebRequest.Create(URL) as HttpWebRequest;
request.Credentials = new NetworkCredential(Settings.Default.LicenseUser, Settings.Default.LicensePassword);
request.KeepAlive = false;
request.Timeout = 5000;
request.Proxy = null;
// Read stream
string responseString = String.Empty;
try
{
using (var response = request.GetResponse())
{
using (Stream objStream = response.GetResponseStream())
{
using (StreamReader objReader = new StreamReader(objStream))
{
responseString = objReader.ReadToEnd();
objReader.Close();
}
objStream.Flush();
objStream.Close();
}
response.Close();
}
}
catch (WebException ex)
{
throw new LicenseServerUnavailableException();
}
finally
{
request.Abort();
request = null;
GC.Collect();
}
return responseString;
}
抛出的 WebException 是:
{“操作已超时”} [System.Net.WebException]:{“操作已超时”} 数据:{System.Collections.ListDictionaryInternal} 帮助链接:空 内部异常:空 消息:“操作已超时” 来源:《系统》 StackTrace:“位于 C:\Users\jd\SVN\jd\Products\Development\JAD.Licensing\JAD 中的 System.Net.HttpWebRequest.GetResponse()\r\n IQX.Licensing.License.GetQLMResponse(String URL) .Licensing\License.cs:第 373 行” 目标站点:{System.Net.WebResponse GetResponse()}
更新:好的所以下面的代码现在可以工作了。 servicePoint 将超时设置为接近 4 分钟。更改请求对象上的 ServicePoint.ConnectionLeaseTimeout
意味着该请求现在会在 5000 毫秒后被销毁。感谢大家的帮助以及这 2 页:
- http://blogs.msdn.com/b/adarshk/archive/2005/01/02/345411.aspx
http://msdn.microsoft.com/en-us/library/6hszazfz(v=VS.80).aspx
私有字符串 GetQLMResponse(字符串 URL) { HttpWebRequest 请求 = WebRequest.Create(URL) as HttpWebRequest; request.Credentials = new NetworkCredential(Settings.Default.LicenseUser, Settings.Default.LicensePassword); 请求.KeepAlive = false; 请求超时= 5000; 请求代理 = null; request.ServicePoint.ConnectionLeaseTimeout = 5000; request.ServicePoint.MaxIdleTime = 5000; // 读取流 字符串responseString = String.Empty; 尝试 { 使用 (WebResponse 响应 = request.GetResponse()) { 使用 (Stream objStream = response.GetResponseStream()) { 使用 (StreamReader objReader = new StreamReader(objStream)) { 响应字符串 = objReader.ReadToEnd(); objReader.Close(); } objStream.Flush(); objStream.Close(); } 响应.关闭(); } } catch(WebException 前) { 抛出新的 LicenseServerUnavailableException(); } 最后 { 请求.Abort(); } 返回响应字符串; }
Why does the following code Timeout the second (and subsequent) time it is run?
The code hangs at:
using (Stream objStream = request.GetResponse().GetResponseStream())
and then causes a WebException saying that the request has timed out.
I have tried this with a WebRequest
and HttpWebRequest
Edit: It seems the code is falling over in request.GetResponse()
Edit: This post suggests it may be a GC issue --> http://www.vbforums.com/showthread.php?t=610043 - as per this post the issue is mitigated if Fiddler is open in the background.
The server is there and available for requests.
private string GetQLMResponse(string URL)
{
HttpWebRequest request = WebRequest.Create(URL) as HttpWebRequest;
request.Credentials = new NetworkCredential(Settings.Default.LicenseUser, Settings.Default.LicensePassword);
request.KeepAlive = false;
request.Timeout = 5000;
request.Proxy = null;
// Read stream
string responseString = String.Empty;
try
{
using (var response = request.GetResponse())
{
using (Stream objStream = response.GetResponseStream())
{
using (StreamReader objReader = new StreamReader(objStream))
{
responseString = objReader.ReadToEnd();
objReader.Close();
}
objStream.Flush();
objStream.Close();
}
response.Close();
}
}
catch (WebException ex)
{
throw new LicenseServerUnavailableException();
}
finally
{
request.Abort();
request = null;
GC.Collect();
}
return responseString;
}
Thrown WebException is:
{"The operation has timed out"}
[System.Net.WebException]: {"The operation has timed out"}
Data: {System.Collections.ListDictionaryInternal}
HelpLink: null
InnerException: null
Message: "The operation has timed out"
Source: "System"
StackTrace: " at System.Net.HttpWebRequest.GetResponse()\r\n at IQX.Licensing.License.GetQLMResponse(String URL) in C:\Users\jd\SVN\jd\Products\Development\JAD.Licensing\JAD.Licensing\License.cs:line 373"
TargetSite: {System.Net.WebResponse GetResponse()}
Update: OK So the following code now works. The servicePoint was setting the timeout to be near 4 minutes. Changing ServicePoint.ConnectionLeaseTimeout
on the request object means that the request is now destroyed after 5000ms. Thanks to all for your help and also to these 2 pages:
- http://blogs.msdn.com/b/adarshk/archive/2005/01/02/345411.aspx
http://msdn.microsoft.com/en-us/library/6hszazfz(v=VS.80).aspx
private string GetQLMResponse(string URL) { HttpWebRequest request = WebRequest.Create(URL) as HttpWebRequest; request.Credentials = new NetworkCredential(Settings.Default.LicenseUser, Settings.Default.LicensePassword); request.KeepAlive = false; request.Timeout = 5000; request.Proxy = null; request.ServicePoint.ConnectionLeaseTimeout = 5000; request.ServicePoint.MaxIdleTime = 5000; // Read stream string responseString = String.Empty; try { using (WebResponse response = request.GetResponse()) { using (Stream objStream = response.GetResponseStream()) { using (StreamReader objReader = new StreamReader(objStream)) { responseString = objReader.ReadToEnd(); objReader.Close(); } objStream.Flush(); objStream.Close(); } response.Close(); } } catch (WebException ex) { throw new LicenseServerUnavailableException(); } finally { request.Abort(); } return responseString; }
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
继之前的答案之后,我想补充一些内容。默认情况下,
HttpWebRequest
只允许到同一主机的 2 个连接(这是 HTTP 1.1“好”),是的,它可以被覆盖,不,我不会告诉你在这个问题中如何,你必须问另一位:)
我认为你应该看看这篇文章。
我认为您仍然没有完全处理与 HttpWebRequest 连接的所有资源,因此连接池发挥作用,这就是问题所在。我不会尝试反对每服务器 2 个连接的规则,除非你真的必须这么做。
正如上面的海报之一所指出的,在这种情况下,Fiddler 对您造成了一些伤害。
我会在 catch 后添加一个很好的
finally {}
子句,并确保如上面的帖子所述,所有流都被刷新、关闭,并且对请求对象的引用设置为 null。如果这有帮助,请告诉我们。
On the heels of the previous answers, I wanted to add a couple more things. By default
HttpWebRequest
allows only 2 connections to the same host (this is HTTP 1.1 "niceness"),Yes, it can be overriden, no I won't tell you how in this question, you have to ask another one :)
I think you ought to look at this post.
I think that you are still not quite disposing of all your resources connected with the HttpWebRequest, so the connection pooling comes into play and that's the problem. I wouldn't try to fight the 2 connections per server rule, unless you really have to.
As one of the posters above noted, Fiddler is doing you a bit of a disservice in this case.
I'd add a nice
finally {}
clause after your catch and make sure that as the above post notes, all streams are flushed, closed and references to the request object are set to null.Please let us know if this helps.
由
request.GetReponse()
获得的WebResponse
必须正确处理。试试这个(删除request.Abort()
和GC.Collect()
调用):编辑:
由于它仍然不起作用,我建议您使用空的 Windows 应用程序进行测试。这样,您可以隔离 app.config 问题或每个主机的最大并发调用*(您是否在应用程序中的其他位置对此主机使用其他 Webrequest 对象;哪些 Web 响应未正确处理?)。
希望这能解决您的问题,我没有主意了!
The
WebResponse
obtained byrequest.GetReponse()
MUST be disposed properly. Try this (removingrequest.Abort()
andGC.Collect()
calls):Edit:
Since it still does not work, I suggest you to test this with an empty windows application. This way, you could isolate app.config problems or maximum concurrent calls per host* (are you using other webrequest object somewhere else in your application to this host; which webresponse are not disposed properly?).
Hope this solve your problem, I am out of ideas!
正如您所说,在后台运行 fiddler 可以缓解这个问题。这是因为 fiddler 强制关闭任何响应。扩展 Sam BI 的上述帖子将确保响应像这样关闭:
另外,可能值得将代理设置为 null,如下所示:
因为 .NET 框架将出去搜索代理,除非您明确执行此操作。当 fiddler 运行时,这种影响会减轻,因为会直接找到 fiddler 代理。
As you have stated, running fiddler in the background would mitigate the issue. This is because fiddler force closes any responses. Extending on the above post from Sam B I would ensure that the response is closed like so:
Also it may be worth setting the proxy to null like so:
As the .NET framework will go out searching for a proxy unless you explicitly do this. When fiddler is running this effect would be mitigated as fiddlers proxy would be found directly.
尽管正确处置/刷新/关闭所有内容,但对服务器的后续请求超时仍遇到同样的问题。尝试刷新您的连接组,对我有用:
另外,确保您不会无意中在应用程序中的其他位置创建未正确终止/处置的其他 HttpWebRequest/Request 对象,因为这会增加服务点中的连接数量。
ran into the same problem with timeouts on subsequent requests to the server despite disposing/flushing/closing everything properly. try flushing your connection group, worked for me:
also, ensure you're not inadvertently creating other HttpWebRequest/Request objects elsewhere in your application that aren't being properly terminated/disposed, as this will increase the numbers of connections in the Service Point.
我遇到了同样的问题,并确保在创建的每个请求对象上调用
Abort()
方法来解决它。I had the same issue, and I resolved it ensuring I call the
Abort()
method on each of the request object created.您是否有可能使用默认名称为 WindowsFormsAppN 的测试应用程序?我遇到了同样的问题,我花了一周的时间进行调试,因为它在我的生产代码中有效,但在我正在构建的简单测试解决方案中无效。最后,我确定此行为是使用默认解决方案名称而不是正确命名的解决方案所特有的。
编辑:我发现我的问题与使用 BitDefender 作为我的 AV 软件有关。 WindowsFormsAppN 程序全部被阻止。
By any chance were you using a test app with the default name of WindowsFormsAppN? I had the same problem that I spent a week debugging because it worked in my production code but not in a simple test solution I was building. In the end, I determined this behavior was unique to using the default solution name instead of a properly named solution.
Edit: I discovered my issue was related to using BitDefender as my AV software. The WindowsFormsAppN programs were all blocked.
我阅读了上面标记为答案的帖子,但上面的内容对我来说并没有真正起作用。
我最终使用 using 标签重写了代码,并添加了其他人在这里推荐的 CloseConnectionGroup 段。最终代码如下所示:
I read the post tagged as answer above and it didn't really work for me above.
I ended up rewriting the code using the using tags and added a CloseConnectionGroup segment someone else recommended here. Ultimately this is what the code looks like:
添加此内容后我就完成了
Done with me when add this
对于在 vb.net 中寻找第二次超时的人:
确保您一直在使用:
response.close()
response.dispose()
每次使用网络响应后,
for anyone looking for second time timeouts in vb.net:
make sure you have been using:
response.close()
response.dispose()
after every time you have used your webresponse.
我已将 http 超时设置为 10 分钟,这对我有用。
设置为
timeout=infinite
需要更多时间,并且我的程序处于挂起模式。I've set http time out to 10 minutes and it worked for me.
Setting to
timeout=infinite
was taking more time and my program was going in hung mode.