HttpWebRequest超时第二个电话
为什么下面的代码超时运行的第二个(和后续)时间?
代码挂在:
using (Stream objStream = request.GetResponse().GetResponseStream())
然后导致WebException说该请求已超时。
我已经试过这与WebRequest
和HttpWebRequest
编辑:看起来代码是在request.GetResponse()
编辑:这个职位表明它可能是一个GC问题 – > http://www.vbforums.com/showthread.php?t=610043 – 根据这个职位,如果提琴手是在后台打开缓解的问题。
服务器在那里,可用于请求。
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是:
{“The operation has timed out”} [System.Net.WebException]:{“The operation has timed out”} Data:{System.Collections.ListDictionaryInternal} HelpLink:null InnerException:null消息:“操作已超时”在C:\ Users \ jd \ SVN \ jd \ Products \ Development \中的IQX.Licensing.License.GetQLMResponse(String URL)上的System.Net.HttpWebRequest.GetResponse()\ r \ JAD.Licensing \ JAD.Licensing \ License.cs:373行“TargetSite:{System.Net.WebResponse GetResponse()}
更新:好所以下面的代码现在工作。 servicePoint将超时设置为接近4分钟。 请求对象上的更改ServicePoint.ConnectionLeaseTimeout
意味着请求现在在5000ms后被销毁。 感谢大家的帮助,以及这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
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; }
在之前的答案之后,我想添加更多的东西。 默认情况下, HttpWebRequest
只允许2个连接到同一个主机(这是HTTP 1.1“不错”),
是的,它可以被覆盖,不,我不会告诉你如何在这个问题上,你必须问另一个:)我认为你应该看看这个职位 。
我认为你还没有完全处理与HttpWebRequest连接的所有资源,所以连接池就会起作用,这就是问题所在。 除非你真的需要,否则我不会去争取每个服务器规则的2个连接。
正如上面提到的海报之一,在这种情况下,提琴手对你有一些伤害。
我会在catch之后添加一个很好的finally {}
子句,并确保如上所述,所有stream都被刷新,closures,并且对请求对象的引用设置为null。
请让我们知道这是否有帮助。
request.GetReponse()
获得的WebResponse
必须正确处理。 试试这个(删除request.Abort()
和GC.Collect()
调用):
using (var wresponse = request.GetResponse()) { using (Stream objStream = wresponse.GetResponseStream()) { // ... } }
编辑 :由于它仍然不起作用,我build议你用一个空的Windows应用程序来testing这个。 这样,你可以分离每个主机的app.config问题或者最大的并发调用*(你是否在你的应用程序中的其他webrequest对象中使用了这个主机;哪个webresponse没有正确处理?)。
希望这能解决你的问题,我出于主意!
- 见Jon Skeet 在这里的答案。
正如你所说,在后台运行提琴手将缓解这个问题。 这是因为提琴手力量closures任何反应。 从Sam BI的上述post扩展将确保响应如下所示:
using (var wresponse = request.GetResponse()) { using (Stream objStream = wresponse.GetResponseStream()) { // ... } wresponse.close(); }
也可以将代理设置为null,如下所示:
request.Proxy = Null;
由于.NET框架将会去寻找一个代理,除非你明确地做到这一点。 当提琴手正在运行,这个效果会被缓解,因为小提琴代理将被直接find。
在后续对服务器的请求超时的情况下遇到同样的问题,尽pipe正确地处理/清除/closures所有的东西。 尝试冲洗你的连接组,为我工作:
myRequest.ServicePoint.CloseConnectionGroup(myRequest.ConnectionGroupName);
另外,确保不会在应用程序的其他地方无意中创build其他HttpWebRequest / Request对象,因为这会增加服务点中的连接数量。
我有同样的问题,我解决了它确保我在每个创build的请求对象调用Abort()
方法。
我已经设置了http时间到10分钟,它为我工作。
设置为timeout=infinite
是需要更多的时间,我的程序进入挂起模式。