2010-01-14 106 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; 
相關問題