Dar*_*bio 43 c# garbage-collection http webrequest httpwebrequest
为什么以下代码超时运行它的第二个(及后续)时间?
代码挂起:
using (Stream objStream = request.GetResponse().GetResponseStream())
Run Code Online (Sandbox Code Playgroud)
然后导致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;
}
Run Code Online (Sandbox Code Playgroud)
抛出的WebException是:
{"操作已超时"} [System.Net.WebException]:{"操作已超时"}数据:{System.Collections.ListDictionaryInternal} HelpLink:null InnerException:null消息:"操作已超时"来源:"系统"StackTrace:"在System.Net.HttpWebRequest.GetResponse()\ r \n,位于C:\ Users\jd\SVN\_Jd\Products\Development \中的IQX.Licensing.License.GetQLMResponse(String URL) JAD.Licensing\JAD.Licensing\License.cs:第373行"TargetSite:{System.Net.WebResponse GetResponse()}
更新:确定以下代码现在可以正常工作.servicePoint将超时设置为接近4分钟.更改ServicePoint.ConnectionLeaseTimeout请求对象意味着请求现在在5000ms后被销毁.感谢大家的帮助以及这2页:
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;
}
Run Code Online (Sandbox Code Playgroud)daw*_*ber 28
在之前的答案之后,我想补充一些东西.默认情况下HttpWebRequest,只允许2个连接到同一主机(这是HTTP 1.1"niceness"),
是的,它可以被覆盖,不,我不会告诉你如何在这个问题中,你必须问另一个:)我认为你应该看看这篇文章.
我认为您仍然没有完全处理与HttpWebRequest相关的所有资源,因此连接池发挥作用,这就是问题所在.除非你真的需要,否则我不会尝试对每个服务器规则的2个连接进行对抗.
正如上面提到的其中一张海报,Fiddler在这种情况下对你有点不利.
我会finally {}在你的catch之后添加一个nice 子句,并确保如上面的帖子所述,所有流都被刷新,关闭,并且对请求对象的引用被设置为null.
如果有帮助,请告诉我们.
Sam*_*m B 21
必须妥善处理所WebResponse获得的request.GetReponse().试试这个(删除request.Abort()和GC.Collect()调用):
using (var wresponse = request.GetResponse())
{
using (Stream objStream = wresponse.GetResponseStream())
{
// ...
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:由于它仍然无法正常工作,我建议您使用空的Windows应用程序进行测试.这样,您可以隔离app.config问题或每个主机的最大并发调用*(您是否在应用程序中的其他位置使用其他webrequest对象到此主机;哪些webresponse未正确处理?).
希望这能解决你的问题,我的想法!
正如您所说,在后台运行提琴手可以缓解这个问题.这是因为提琴手力量会关闭任何回应.从Sam BI扩展上述帖子将确保响应如此关闭:
using (var wresponse = request.GetResponse())
{
using (Stream objStream = wresponse.GetResponseStream())
{
// ...
}
wresponse.close();
}
Run Code Online (Sandbox Code Playgroud)
也可能值得将代理设置为null,如下所示:
request.Proxy = Null;
Run Code Online (Sandbox Code Playgroud)
因为.NET框架会出去搜索代理,除非你明确地这样做.当fiddler运行时,这种效果会被减轻,因为可以直接找到小提琴代理.
尽管正确处理/刷新/关闭了所有内容,但随后对服务器的请求却遇到了超时问题。尝试刷新您的连接组,为我工作:
myRequest.ServicePoint.CloseConnectionGroup(myRequest.ConnectionGroupName);
Run Code Online (Sandbox Code Playgroud)
另外,请确保您不会在应用程序中的其他地方意外地创建未正确终止/处置的其他HttpWebRequest / Request对象,因为这将增加服务点中的连接数量。