webentwicklung-frage-antwort-db.com.de

HttpWebRequest: Die Anfrage wurde abgebrochen: Die Anfrage wurde abgebrochen

Ich habe an der Entwicklung einer Art Middle-Man-Anwendung gearbeitet, bei der Text für HTTP-Post-Anforderungen für eine Reihe von Datumsangaben (normalerweise 7 auf einmal) in ein CMS-Backend hochgeladen wird. Ich verwende HttpWebRequest, um dies zu erreichen. Es scheint für das erste Datum gut zu funktionieren, aber wenn es das zweite Datum startet, erhalte ich die System.Net.WebException: Die Anforderung wurde abgebrochen: Die Anforderung wurde abgebrochen.

Ich habe herumgesucht und die folgenden großen Hinweise gefunden:

http://social.msdn.Microsoft.com/Forums/en-US/netfxnetcom/thread/0d0afe40-c62a-4089-9d8b-fb4d206434dc

http://www.jaxidian.org/update/2007/05/05/8

http://arnosoftwaredev.blogspot.com/2006/09/net-20-httpwebrequestkeepalive-and.html

Und sie waren nicht zu hilfreich. Ich habe versucht, den GetWebReuqest zu überladen, aber das macht keinen Sinn, weil ich diese Funktion nicht benutze.

Hier ist mein Code: http://Pastebin.org/115268

Ich bekomme den Fehler in Zeile 245, nachdem er mindestens einmal erfolgreich ausgeführt wurde.

Ich würde mich über jede Hilfe freuen, die ich bekommen kann, da dies der letzte Schritt in einem Projekt ist, an dem ich schon einmal gearbeitet habe. Dies ist mein erstes C #/VS-Projekt, also bin ich offen für alle Tipps, aber ich möchte mich darauf konzentrieren, dieses Problem zuerst zu lösen.

Vielen Dank!

20
Emeka

Die häufig im Internet aufgelistete Lösung scheint darin zu bestehen, die KeepAlive-Eigenschaft von HttpWebRequest auf false zu setzen. Dies kann das Problem beheben, wenn die Hauptursache darin besteht, dass die Verbindung voraussichtlich wiederverwendet wird, obwohl sie nach einiger Zeit tatsächlich automatisch geschlossen wurde. Das ständige Öffnen und Schließen von Verbindungen ist jedoch ein Leistungsproblem.

Eine andere mögliche Lösung, die ich bei diesem Problem verwendete, bestand in der Erweiterung der Timeout-Eigenschaften: WebRequest.ReadWriteTimeout, WebRequest.Timeout, RequestStream.WriteTimeout und RequestStream.ReadTimeout. Bitte beachten Sie, dass dies in Millisekunden ist. Daher sollten Sie für die Timeouts 1000 * 60 * 10 (10 Minuten) oder 600.000 (wenn Sie glauben, dass Sie wissen, was das bedeutet ...) sind. Sie können testen, ob dies die wahrscheinlichere Ursache des Problems ist, indem Sie die Dateigröße reduzieren.

BTW. Ihr Code war nicht mehr auf der aufgelisteten Website. Sie können es in den Text Ihres Beitrags aufnehmen, wenn es sich noch um ein Problem handelt.

18
Registered User

Hier ist die einzige Lösung, die für mich funktioniert:

http://blogs.msdn.com/b/johan/archive/2006/11/15/are-you-getting-outofmemoryexceptions-when-uploading-large-files.aspx

Diese Zeilen sind der Schlüssel:

    HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(yourUri);
    wr.KeepAlive = false;
    wr.Timeout = System.Threading.Timeout.Infinite;
    wr.ProtocolVersion = HttpVersion.Version10;

Und hier:

wr.AllowWriteStreamBuffering = false;
12
RoundOutTooSoon

Eine kurze Zusammenfassung meiner Anwendung: Ich habe bis zu 16 identische Threads, die gleichzeitig HTTP-Anforderungen ausführen. Jeder dieser Threads fordert verschiedene Webserver zusammen mit eindeutigen lokalen Endpunkten an. Nun muss die Funktion, die diese Aufrufe durchführt, drei aufeinanderfolgende HTTP-Anforderungen (an denselben Webserver) erstellen und einige Aggregationen durchführen.

Basierend auf den in den obigen Links angegebenen Lösungen hat die folgende Kombination für mich funktioniert.

System.Net.ServicePointManager.DefaultConnectionLimit = 200;
System.Net.ServicePointManager.MaxServicePointIdleTime = 2000;
System.Net.ServicePointManager.MaxServicePoints = 1000;
System.Net.ServicePointManager.SetTcpKeepAlive(false, 0, 0);

HttpWebRequest webRequest1 = (HttpWebRequest)WebRequest.Create("http://" + gatewayIP
 + "/xslt?");
webRequest1.KeepAlive = false;
webRequest1.Timeout = 2000;
//Do other stuff here...
//Close response stream

Thread.Sleep(1000); //This delay seems to help. Obviously very specific to the server

HttpWebRequest webRequest2 = (HttpWebRequest)WebRequest.Create("http://" + gatewayIP
 + "/xslt?");
webRequest2.KeepAlive = false;
webRequest2.Timeout = 2000;
//Do other stuff here...
//and so on...
3
tman

Ich unterstütze einen Azure-Webdienst, der Dateien von der mobilen App akzeptiert und in den Azure-Blob-Speicher überträgt, indem der Stream der eingehenden Anforderung in den Stream eines ausgehenden HttpWebRequest kopiert wird, z. 

using (Stream requestStream = outgoingRequest.GetRequestStream()) 
{ 
    context.Request.InputStream.copyTo(requestStream)
    requestStream.Flush();
    requestStream.Close();
}

Hin und wieder warf die Ausnahme "Die Anforderung wurde abgebrochen: Die Anforderung wurde abgebrochen" während Close () ab, oder am Ende der Verwendung von {}, wenn Sie Close () nicht verwenden. Ich habe alle oben vorgeschlagenen Lösungen ausprobiert und keine davon hat funktioniert, bis ich die eigentliche Fehlerursache gefunden habe, die ich hier mitteilen möchte: Manchmal ist der InputStream der eingehenden Anfrage abgeschnitten und enthält nicht den gesamten Dateiinhalt. Wenn dieser unvollständige Stream in den Stream der ausgehenden Anforderung kopiert wird, gibt die ausgehende Anforderung während des Close () - Befehls oder am Ende des using {} - Blocks einen Fehler aus. Dies ist ein wenig irreführend, da die Ursache nicht die ausgehende Anfrage ist, sondern
Der unvollständige Datenstrom, der in ihn kopiert wird. Um dies zu vermeiden, fügen Sie eine Prüfung für die Länge des eingehenden Anforderungsdatenstroms hinzu, indem Sie die Dateilänge vergleichen, die im Header der aufrufenden App gespeichert werden muss, z.

    if (context.Request.InputStream.Length != int.Parse(context.Request.Headers["file-length"])) 
    { 
        //handle this case here, e.g.
        context.Response.StatusCode = 500;
        context.Response.StatusDescription = "(500) Internal Server Error";
        context.Response.End();
    }
    else
    {
         //proceed with copying the stream (the first code snippet)
    }
0
user2116792