Ich verwende eine Open Source-Bibliothek, um eine Verbindung zu meinem Webserver herzustellen. Ich war besorgt, dass der Webserver extrem langsam lief, und habe dann versucht, einen einfachen Test in Ruby durchzuführen, und diese Ergebnisse erhalten
Ruby-Programm: 2,11 Sekunden für 10 HTTP-GETs
Ruby-Programm: 18,13 Sekunden für 100 HTTP-GETs
C # -Bibliothek: 20,81 Sekunden für 10 HTTP-GETs
C # -Bibliothek: 36847,46 Sekunden für 100 HTTP-GETs
Ich habe ein Profil erstellt und festgestellt, dass das Problem diese Funktion ist:
private HttpWebResponse GetRawResponse(HttpWebRequest request) {
HttpWebResponse raw = null;
try {
raw = (HttpWebResponse)request.GetResponse(); //This line!
}
catch (WebException ex) {
if (ex.Response is HttpWebResponse) {
raw = ex.Response as HttpWebResponse;
}
}
return raw;
}
Es dauert mehr als 1 Sekunde, bis die markierte Zeile von selbst abgeschlossen ist, während das Ruby-Programm, das 1 Anfrage stellt, 0,3 Sekunden dauert. Ich mache auch alle diese Tests auf 127.0.0.1, so dass die Netzwerkbandbreite kein Problem ist.
Was könnte diese enorme Verlangsamung verursachen?
AKTUALISIEREN
Überprüfen Sie die geänderten Benchmark-Ergebnisse. Ich habe tatsächlich mit 10 GETs und nicht mit 100 getestet und die Ergebnisse aktualisiert.
quelle
Antworten:
Was ich als Hauptschuldigen bei langsamen Webanfragen herausgefunden habe, ist die Proxy-Eigenschaft. Wenn Sie diese Eigenschaft vor dem Aufrufen der GetResponse-Methode auf null setzen, überspringt die Abfrage den Autodetect-Schritt des Proxys:
request.Proxy = null; using (var response = (HttpWebResponse)request.GetResponse()) { }
Die automatische Abfrage des Proxys dauerte bis zu 7 Sekunden, bevor die Antwort zurückgegeben wurde. Es ist etwas ärgerlich, dass diese Eigenschaft für das HttpWebRequest-Objekt standardmäßig aktiviert ist.
quelle
GetResponse
Anruf in eineusing
Direktive zu packen, da die Anzahl der Verbindungen begrenzt ist und Sie warten müssen, bis sie eine Zeitüberschreitung aufweisen, wenn Sie sie nicht ordnungsgemäß schließen.Dies hängt möglicherweise damit zusammen, dass Sie mehrere Verbindungen gleichzeitig öffnen. Standardmäßig ist die maximale Anzahl offener HTTP-Verbindungen auf zwei festgelegt. Versuchen Sie, dies zu Ihrer .config-Datei hinzuzufügen, und prüfen Sie, ob es hilft:
<system.net> ....... <connectionManagement> <add address="*" maxconnection="20"/> </connectionManagement> </system.net>
quelle
Ich hatte ein ähnliches Problem mit einem VB.Net MVC-Projekt.
Auf meinem PC (Windows 7) dauerte es weniger als 1 Sekunde, um die Seitenanforderungen zu erfüllen, auf dem Server (Windows Server 2008 R2) dauerte es für jede Seitenanforderung mehr als 20 Sekunden.
Ich habe versucht, den Proxy auf Null zu setzen
Und Ändern der Konfigurationsdatei durch Hinzufügen
<system.net> ....... <connectionManagement> <add address="*" maxconnection="20"/> </connectionManagement> </system.net>
Dies reduzierte die langsamen Seitenanforderungszeiten auf dem Server immer noch nicht. Am Ende bestand die Lösung darin, die Option "Einstellungen automatisch erkennen" in den IE-Optionen auf dem Server selbst zu deaktivieren . (Wählen Sie unter Extras -> Internetoptionen die Registerkarte Verbindungen. Klicken Sie auf die Schaltfläche LAN-Einstellungen.)
Unmittelbar nachdem ich diese Browseroption auf dem Server deaktiviert hatte, sanken alle Seitenanforderungszeiten von mehr als 20 Sekunden auf unter 1 Sekunde.
quelle
Ich bemerkte eine Verlangsamung ähnlich der OP in diesem Bereich, die beim Erhöhen der MaxConnections etwas besser wurde.
ServicePointManager.DefaultConnectionLimit = 4;
Nachdem diese Anzahl von WebRequests erstellt wurde, kamen die Verzögerungen zurück.
Das Problem in meinem Fall war, dass ich einen POST anrief und mich nicht um die Antwort kümmerte, also nichts aufnahm oder etwas damit machte. Leider schwebte die WebRequest so lange herum, bis das Zeitlimit überschritten wurde.
Die Lösung bestand darin, die Antwort aufzunehmen und einfach zu schließen.
WebRequest webRequest = WebRequest.Create(sURL); webRequest.Method = "POST"; webRequest.ContentLength = byteDataGZ.Length; webRequest.Proxy = null; using (var requestStream = webRequest.GetRequestStream()) { requestStream.WriteTimeout = 500; requestStream.Write(byteDataGZ, 0, byteDataGZ.Length); requestStream.Close(); } // Get the response so that we don't leave this request hanging around WebResponse response = webRequest.GetResponse(); response.Close();
quelle
HttpWebResponse
und ich habe eines gefunden, das ich nicht geschlossen habe.Verwenden Sie einen anderen Computer als localhost und verwenden Sie dann WireShark, um zu sehen, was wirklich über das Kabel läuft.
Wie andere gesagt haben, kann es eine Reihe von Dingen sein. Ein Blick auf die Dinge auf TCP-Ebene sollte ein klares Bild ergeben.
quelle
Ich weiß nicht, wie genau ich zu dieser Problemumgehung gekommen bin. Ich hatte noch keine Zeit für Nachforschungen, also liegt es an euch. Es gibt einen Parameter, den ich wie folgt verwendet habe (im Konstruktor meiner Klasse, bevor das HTTPWebRequest-Objekt instanziiert wurde):
System.Net.ServicePointManager.Expect100Continue = false;
Ich weiß nicht genau warum, aber jetzt sehen meine Anrufe viel schneller aus.
quelle
Ich weiß, dass dies ein alter Thread ist, aber ich habe den ganzen Tag mit langsamem HttpWebRequest verloren und jede bereitgestellte Lösung ohne Glück ausprobiert. Jede Anfrage nach einer Adresse dauerte mehr als eine Minute.
Schließlich lag ein Problem mit meiner Antivirus-Firewall (Eset) vor . Ich verwende eine Firewall mit interaktivem Modus, aber Eset wurde irgendwie vollständig ausgeschaltet. Das führte dazu, dass die Anfrage für immer andauerte. Nach dem Einschalten von Eset und dem Ausführen der Anforderung wird eine Firewall-Meldung angezeigt, und nach der Bestätigung wird die Anforderung weniger als eine Sekunde lang ausgeführt .
quelle
Ich habe alle hier beschriebenen Lösungen ohne Glück ausprobiert, der Anruf dauerte ca. 5 Minuten.
Was war das Problem: Ich brauchte dieselbe Sitzung und offensichtlich dieselben Cookies (Anfrage auf demselben Server), also habe ich die Cookies von Request.Cookies in WebRequest.CookieContainer neu erstellt . Die Reaktionszeit betrug ca. 5 Minuten.
Meine Lösung: Den Cookie-Code und bam auskommentiert! Der Anruf dauerte weniger als eine Sekunde.
quelle
Für mich bestand das Problem darin, dass ich LogMeIn Hamachi installiert hatte - ironischerweise, um dasselbe Programm aus der Ferne zu debuggen, das dann diese extreme Langsamkeit zeigte.
Zu Ihrer Information, das Deaktivieren des Hamachi-Netzwerkadapters reichte nicht aus, da der Windows-Dienst den Adapter anscheinend wieder aktiviert.
Auch das erneute Herstellen einer Verbindung zu meinem Hamachi-Netzwerk hat das Problem nicht gelöst. Nur das Deaktivieren des Adapters (durch Deaktivieren des Windows-Dienstes LogMeIn Hamachi) oder vermutlich das Deinstallieren von Hamachi hat das Problem für mich behoben.
Ist es möglich zu fragen, ob
HttpWebRequest
Sie über einen bestimmten Netzwerkadapter ausgehen möchten?quelle
Das hat bei mir funktioniert:
<configuration> <system.net> <defaultProxy enabled="false"/> </system.net> </configuration>
Gutschrift : Langsame HTTPWebRequest beim ersten Start des Programms
quelle
Für mich
HttpWebRequest
betrug das Aufrufen einer API im Durchschnitt 40 ms und das Aufrufen einer API auf einem Server durchschnittlich 270 ms. Der Anruf über Postman betrug in beiden Umgebungen durchschnittlich 40 ms. Keine der Lösungen in diesem Thread hat für mich einen Unterschied gemacht.Dann fand ich diesen Artikel, in dem der Nagle-Algorithmus erwähnt wurde:
Das Einstellen
ServicePoint.UseNagleAlgorithm
auffalse
war die Magie, die ich brauchte, es machte einen großen Unterschied und die Leistung auf dem Server ist jetzt fast identisch mit der lokalen.var webRequest = (HttpWebRequest)WebRequest.Create(url); webRequest.Method = "POST"; webRequest.ServicePoint.Expect100Continue = false; webRequest.ServicePoint.UseNagleAlgorithm = false; // <<<this is the important bit
Beachten Sie, dass dies bei kleinen Datenmengen bei mir funktioniert hat. Wenn Ihre Anfrage jedoch große Datenmengen enthält, kann es sinnvoll sein, dieses Flag abhängig von der Größe der Anfrage / der erwarteten Größe der Antwort abhängig zu machen.
quelle
In meinem Fall
AspxAutoDetectCookieSupport=1
zum Code hinzufügen und das Problem wurde gelöstUri target = new Uri("http://payroll"); string responseContent; HttpWebRequest request = (HttpWebRequest)WebRequest.Create(target); request.CookieContainer = new CookieContainer(); request.CookieContainer.Add(new Cookie("AspxAutoDetectCookieSupport", "1") { Domain = target.Host }); using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) { using (Stream responseStream = response.GetResponseStream()) { using (StreamReader sr = new StreamReader(responseStream)) responseContent = sr.ReadToEnd(); } }
quelle
Wir hatten das gleiche Problem mit der Web-App. Wir haben 5 Sekunden auf die Antwort gewartet. Wenn wir den Benutzer in applicationPool auf IIS in networkService ändern, kam die Antwort weniger als 1 Sekunde an
quelle