2010-01-14 15 views
26

Ich versuche, eine Reihe von Dateien über HTTP mit HttpWebRequest zu holen. Die erste Anfrage läuft gut, aber das zweite Mal durch den gleichen Code GetResponse() hängt und Timeout. WireShark zeigt, dass für die zweite Anforderung kein HTTP-Datenverkehr gesendet wird. Daher scheint es, dass es sich um ein API-Problem handelt.HttpWebRequest.GetResponse() hängt beim zweiten Aufruf

Nach einigen Untersuchungen habe ich festgestellt, dass es mit der Angabe der Länge des Inhalts zu tun hat: Wenn ich das weglassen, dann funktioniert der Code gut.

Mein Code ist:

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

Die Symptome sehr ähnlich scheinen this question und this question, aber in beiden Fällen die gegebene Rat ist der WebResponse zu entsorgen, die ich bereits tue.

bearbeiten Als Reaktion auf Gregory, hier ist 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; 
} 

bearbeiten: Es stellt sich heraus, dass ich die Todsünde des Entfernens von Code aus meiner Frage begangen, dass ich nicht überprüft hatte, ohne Bezug auf das Problem. Ich hatte die folgenden Zeilen entfernt:

, weil ich dachte, dass content-length nie für eine GET-Anfrage angegeben werden würde. Es stellt sich heraus, dass ich falsch lag. Durch das Entfernen dieser Zeile wird das Problem behoben.

Die einzige Frage, die ich jetzt habe, ist warum? I denke, die angegebene Inhaltslänge ist korrekt, obwohl es möglich ist, ist es um eins. Würde die Angabe einer zu kurzen Inhaltslänge verhindern, dass der vollständige Download stattfindet und die Verbindung offen bleibt? Ich hätte erwartet, dass Close() und/oder Dispose() die Verbindung sowieso beenden sollten.

+0

Können Sie ConfigureRequest post()? – Gregory

+0

Auch, re: http://stackoverflow.com/questions/1386628/webrequest-getresponse-locks-up haben Sie versucht, den Wert zu konfigurieren, den JSkeet zu etwas höher, dh 4 oder 8 erwähnt, und sehen, ob das etwas ändert? – Gregory

+0

@Tim Martin: Welche Zeile hast du entfernt? Die if-Klausel und die Einstellung von ContentLength? Also legen Sie die Inhaltslänge überhaupt nicht fest? Ich habe versucht, die Einstellung von ContentLength zu entfernen, aber ich habe immer noch das gleiche Problem. – Ted

Antwort

9

Stellen Sie sicher, dass Sie jedes Mal ein neues HttpWebRequest erstellen. Zitat aus dem Referenz MSDN auf GetResponse Methode:

Mehrere Anrufe zu GetResponse die gleiche Antwort-Objekt zurück; Die Anforderung wird nicht erneut ausgegeben.

Update 1: Ok. Wie wäre es, wenn Sie versuchen würden, auch den webResponseStream zu schließen - das tun Sie derzeit nicht, Sie schließen nur die webResponse (versuchen nur, die Dinge zu regeln). Ich würde auch zu der HttpWebResponse entsorgen (nicht nur die WebResponse)

Update 2: Die einzige andere Sache, die ich vorschlagen kann, ist ein Blick auf die folgenden Artikel zu haben, die ich sah, als ich habe etwas ähnliches zu dem, was ich ist zu tun: http://www.devnewsgroups.net/dotnetframework/t10805-exception-with-httpwebrequest-getresponse.aspx

Die einzigen nennenswerten Dinge, die ich tue unterschiedlich sind
http://arnosoftwaredev.blogspot.com/2006/09/net-20-httpwebrequestkeepalive-and.html
:
- set webrequest.Keep-Alive = false
- ich habe nicht das Verbindungsmanagement Sachen in der Config (ich Runde nicht Schleife eine Reihe von Anfragen zu machen)

+0

Zeit rund Die Schleife Ich rufe WebRequest.Create (URL) auf, um eine neue Anfrage zu erstellen. –

+0

Danke für die zusätzlichen Vorschläge. Ich schließe jetzt den Stream (es wurde bereits Dispose() Ed), und ich habe auch die HttpWebResponse in einem using-Block verpackt. –

+0

Ich habe versucht KeepAlive = false und die "Verwendung" -Ansatz, bekomme ich immer noch das gleiche Problem. Es sieht so aus, als wäre GetResponse der Täter, aber das Problem ist, dass der POST (die zweite Anfrage) überhaupt nicht gesendet wird (wie MSDN-Zustände), daher wartet die GetResponse auf eine Antwort. – Ted

9
httpWebRequest.Abort(); // before you leave 

Will lösen!

1

Dokumentation für HttpWebRequest.ContentLength sagt:

Alle anderen Wert als -1 in der ContentLength Eigenschaft gibt an, dass die Anfrage Uploads Daten und die Daten nur Methoden, die Daten hochladen können in der Methode Eigenschaft gesetzt werden.

Nachdem die ContentLength-Eigenschaft auf einen Wert festgelegt wurde, muss diese Anzahl an Bytes in den Anforderungsstream geschrieben werden, der durch Aufrufen der GetRequestStream-Methode oder der BeginGetRequestStream-Methode und der EndGetRequestStream-Methode zurückgegeben wird.

Ich vermute, dass es hängt, weil Sie die Inhaltslänge einstellen, aber dann keine Daten hochladen. Man sollte denken, dass es in diesem Fall eine Ausnahme geben sollte, aber anscheinend nicht.

-1

‚Sie müssen die webrequest und WebResponse Objekte mit einer gültigen URI initialisieren:

 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

Können Sie erklären, wie dies die Frage beantwortet? –

+0

Ja, tut mir leid! Ich hatte das gleiche Problem. Sie müssen die webrequest und WebResponse Objekte mit einer gültigen URI initialisieren: Dim Anfrage Wie WebRequest = WebRequest.Create ("http://google.com") Dim Antwort als WebResponse = request.GetResponse() Finaly Sie muss das Antwortobjekt schließen: Schließlich response.Close() Ich hoffe es hilft dir: D –

0

Plase versuchen Verwendung:

  HttpRequestCachePolicy noCachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.NoCacheNoStore); 
     httpWebRequest.CachePolicy = noCachePolicy; 
Verwandte Themen