2010-01-14 167 views
26

我试图通过HTTP获取一系列文件,使用HttpWebRequest。第一个请求通过罚款,但第二次通过相同的代码GetResponse()挂起并超时。 WireShark显示没有为第二个请求发送HTTP流量,所以看起来这是一个API问题。HttpWebRequest.GetResponse()第二次挂起时调用

经过一番调查后,我发现它与指定内容长度有关:如果我不写,代码就可以正常工作。

我的代码是:

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(); 
} 

的症状似乎非常相似,this questionthis question,但在这两种情况下,给出的建议是处置WebResponse的,这我已经在做的。

编辑针对格雷戈里,这里是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; 
} 

编辑:原来我承诺从我的问题删除代码的大罪,我还没有证实是与问题无关。我删除了以下行:

if (m_contentLength > 0) 
     httpWebRequest.ContentLength = m_contentLength; 

因为我认为内容长度永远不会被指定为GET请求。原来我错了。删除这条线可以解决问题。

我现在唯一的问题是为什么?我认为指定的内容长度是正确的,虽然它可能是关闭的。指定内容长度太短会阻止完全下载并导致连接保持开放状态?我会期望Close()和/或Dispose()应该终止连接。

+0

您可以发布ConfigureRequest()? – Gregory 2010-01-14 13:03:41

+0

此外,重试:http://stackoverflow.com/questions/1386628/webrequest-getresponse-locks-up你试过配置JSkeet的值提到更高的东西,即4或8,看看这是否会改变什么? – Gregory 2010-01-14 13:05:47

+0

@Tim Martin:你删除了哪一行? if-clause和ContentLength的设置?所以你根本不设置内容长度?我尝试删除ContentLenght的设置,但我仍然有同样的问题。 – Ted 2011-12-04 19:11:30

回答

9

确保您每次都创建一个新的HttpWebRequest。从上GetResponse方法MSDN参考引用:

到的GetResponse多个调用返回 相同的响应对象;请求 不会重新发布。

更新1: 确定。如果你也尝试关闭webResponseStream,那么你现在不这样做,你只关闭webResponse(只是试图排除)。我还处置httpWebResponse太(不只是提供WebResponse)

更新2: 唯一的其他东西我可以建议是看看,我看了看,当我做类似的东西在下面的文章你在做什么:
http://arnosoftwaredev.blogspot.com/2006/09/net-20-httpwebrequestkeepalive-and.html
http://www.devnewsgroups.net/dotnetframework/t10805-exception-with-httpwebrequest-getresponse.aspx

唯一明显的事情,我做不同的是:
- 设置的WebRequest。的KeepAlive =假
- 我没有连接管理的东西在config(我不环路四周以一系列请求)

+0

每次回合我正在调用WebRequest.Create(url)来创建新请求的循环。 – 2010-01-14 12:27:11

+0

感谢您的其他建议。我现在正在关闭流(它已经是Dispose()ed),并且我还将HttpWebResponse包装在一个使用块中。 – 2010-01-14 13:19:21

+0

我尝试过KeepAlive = false和“使用”方法,但我仍然遇到同样的问题。它看起来像GetResponse是罪魁祸首,但问题是根本没有发送POST(第二个请求)(如MSDN状态),因此GetResponse正在等待答案。 – Ted 2011-12-05 10:16:52

1

文档说:

任何值除-1在的ContentLength属性指示该请求上载的数据,并且上载数据,只有方法允许在方法属性被设置。

将ContentLength属性设置为值后,必须将该字节数写入通过调用GetRequestStream方法或BeginGetRequestStream和EndGetRequestStream方法返回的请求流中。

我怀疑它挂起,因为你设置内容的长度,但没有上传任何数据。人们会认为在这种情况下它应该抛出异常,但显然它没有。

-1

“你需要一个有效的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 
+0

你能解释这是如何回答这个问题的吗? – 2015-03-05 00:36:11

+0

是的,对不起! 我有同样的问题。 你需要一个有效的URI来初始化的WebRequest和WebResponse对象: 昏暗的请求作为的WebRequest = WebRequest.Create( “http://google.com”) 昏暗的响应,WebResponse类= request.GetResponse() Finaly你需要关闭响应对象: 最后 response.Close() 我希望它可以帮助你:D – 2015-03-05 00:42:59

0

Plase尝试使用:

  HttpRequestCachePolicy noCachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.NoCacheNoStore); 
     httpWebRequest.CachePolicy = noCachePolicy; 
相关问题