C# HttpWebRequest.GetResponse() 第二次被调用时挂起
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2063937/
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
HttpWebRequest.GetResponse() hangs the second time it is called
提问by Tim Martin
I'm trying to fetch a series of files via HTTP, using HttpWebRequest. The first request goes through fine, but the second time through the same code GetResponse() hangs and times out. WireShark shows that no HTTP traffic is being sent for the second request, so it would appear that it's an API problem.
我正在尝试使用 HttpWebRequest 通过 HTTP 获取一系列文件。第一个请求通过正常,但第二次通过相同的代码 GetResponse() 挂起并超时。WireShark 显示没有为第二个请求发送 HTTP 流量,因此看起来这是一个 API 问题。
After some investigation, I've discovered that it has to do with specifying the content-length: if I leave this out, then the code works fine.
经过一番调查,我发现它与指定内容长度有关:如果我忽略了这一点,那么代码就可以正常工作。
My code is:
我的代码是:
HttpWebRequest httpWebRequest = ConfigureRequest();
using (WebResponse webResponse = httpWebRequest.GetResponse())
// On the second iteration we never get beyond this line
{
HttpWebResponse httpWebResponse = webResponse as HttpWebResponse;
using (Stream webResponseStream = httpWebResponse.GetResponseStream())
{
if (webResponseStream != null)
{
// Read the stream
}
}
statusCode = httpWebResponse.StatusCode;
httpWebResponse.Close();
}
The symptoms seem very similar to this questionand this question, but in both cases the advice given is to dispose of the WebResponse, which I'm already doing.
症状似乎与this question和this question非常相似,但在这两种情况下,给出的建议都是处理我已经在做的WebResponse。
EditIn response to Gregory, here is ConfigureRequest():
编辑响应 Gregory,这里是 ConfigureRequest():
private HttpWebRequest ConfigureRequest()
{
string sUrl = CreateURL(bucket, key);
HttpWebRequest httpWebRequest = WebRequest.Create(sUrl) as HttpWebRequest;
httpWebRequest.AllowWriteStreamBuffering = false;
httpWebRequest.AllowAutoRedirect = true;
httpWebRequest.UserAgent = this.m_sUserAgent;
httpWebRequest.Method = "GET";
httpWebRequest.Timeout = this.m_iTimeout;
// *** NB: This line was left out of my original posting, and turned out to be
// crucial
if (m_contentLength > 0)
httpWebRequest.ContentLength = m_contentLength;
httpWebRequest.Headers.Add(StaticValues.Amazon_AlternativeDateHeader, timestamp);
httpWebRequest.Headers.Add(StaticValues.HttpRequestHeader_Authorization, StaticValues.Amazon_AWS + " " + aWSAccessKeyId + ":" + signature);
return httpWebRequest;
}
Edit: It turns out I committed the cardinal sin of removing code from my question that I hadn't verified was unrelated to the problem. I had removed the following lines:
编辑:事实证明,我犯了从我尚未验证的问题中删除代码与问题无关的大罪。我删除了以下几行:
if (m_contentLength > 0)
httpWebRequest.ContentLength = m_contentLength;
because I thought that content-length would never be specified for a GET request. It turns out I was wrong. Removing this line fixes the problem.
因为我认为永远不会为 GET 请求指定内容长度。事实证明我错了。删除此行可解决问题。
The only question I now have is why? I thinkthe content length that is specified is correct, though it's possible it's off by one. Would specifying a content length that is too short prevent the full download from taking place and cause the connection to be left open? I would have expected that Close() and / or Dispose() ought to kill the connection anyway.
我现在唯一的问题是为什么?我认为指定的内容长度是正确的,尽管它可能相差一个。指定太短的内容长度是否会阻止完全下载并导致连接保持打开状态?我本来希望 Close() 和/或 Dispose() 无论如何都应该终止连接。
回答by AdaTheDev
Make sure you are creating a NEW HttpWebRequest each time. Quote from the MSDN reference on GetResponsemethod :
确保每次都创建一个新的 HttpWebRequest。引用 MSDN 上关于GetResponse方法的参考 :
Multiple calls to GetResponse return the same response object; the request is not reissued.
多次调用 GetResponse 返回相同的响应对象;该请求不会重新发出。
Update 1:Ok. How about if you try closing the webResponseStream too - you currently don't do that, you're only closing the webResponse (just trying to rule things out). I'd also dispose of the httpWebResponse too (not just the WebResponse)
更新 1:好的。如果您也尝试关闭 webResponseStream 怎么样 - 您目前没有这样做,您只是关闭 webResponse (只是想排除一些事情)。我也会处理 httpWebResponse (不仅仅是 WebResponse)
Update 2:The only other thing I can suggest is to have a look at the following articles that I looked at when I did something similar to what you're doing:
http://arnosoftwaredev.blogspot.com/2006/09/net-20-httpwebrequestkeepalive-and.html
http://www.devnewsgroups.net/dotnetframework/t10805-exception-with-httpwebrequest-getresponse.aspx
更新 2:我唯一能建议的另一件事是看看我在做类似于你正在做的事情时看过的以下文章:
http: //arnosoftwaredev.blogspot.com/2006/09/net -20-httpwebrequestkeepalive-and.html
http://www.devnewsgroups.net/dotnetframework/t10805-exception-with-httpwebrequest-getresponse.aspx
The only noticeable things I do different are:
- set webrequest.KeepAlive = false
- I don't have the connection management stuff in the config (I don't loop round to make a series of requests)
我做的唯一值得注意的事情是:
- 设置 webrequest.KeepAlive = false
- 我在配置中没有连接管理的东西(我没有循环来发出一系列请求)
回答by AdaTheDev
回答by Jim Mischel
Documentation for HttpWebRequest.ContentLengthsays:
HttpWebRequest.ContentLength 的文档说:
Any value other than -1 in the ContentLength property indicates that the request uploads data and that only methods that upload data are allowed to be set in the Method property.
After the ContentLength property is set to a value, that number of bytes must be written to the request stream that is returned by calling the GetRequestStream method or both the BeginGetRequestStream and the EndGetRequestStream methods.
ContentLength 属性中除 -1 之外的任何值表示请求上传数据,并且只允许在 Method 属性中设置上传数据的方法。
将 ContentLength 属性设置为一个值后,必须将该字节数写入通过调用 GetRequestStream 方法或同时调用 BeginGetRequestStream 和 EndGetRequestStream 方法返回的请求流。
I suspect it hangs because you're setting the content length but then not uploading any data. One would think that it should throw an exception in that case, but apparently it doesn't.
我怀疑它挂起是因为您正在设置内容长度但没有上传任何数据。人们会认为在这种情况下它应该抛出异常,但显然它没有。
回答by Aarón Altamirano
'You need to initialize the webrequest and webresponse objects with a valid URI:
'您需要使用有效的 URI 初始化 webrequest 和 webresponse 对象:
Dim request As WebRequest = WebRequest.Create("http://google.com")
Dim response As WebResponse = request.GetResponse()
Function UrlExists(ByVal URL As String) As Boolean
Try
request = WebRequest.Create(URL)
response = request.GetResponse()
Catch ex As Exception
Return False
Finally
response.Close()
End Try
Return True
End Function
回答by kris164
Plase try use:
请尝试使用:
HttpRequestCachePolicy noCachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.NoCacheNoStore);
httpWebRequest.CachePolicy = noCachePolicy;