wake-up-neo.com

HttpWebRequest ist extrem langsam!

Ich verwende eine Open Source-Bibliothek, um eine Verbindung zu meinem Webserver herzustellen. Ich war besorgt, dass der Webserver extrem langsam lief, und dann habe ich versucht, einen einfachen Test in Ruby durchzuführen und diese Ergebnisse zu erzielen

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

Die markierte Zeile dauert mehr als 1 Sekunde, während das Ruby-Programm, das 1 Anforderung vornimmt, 3 Sekunden benötigt. Ich mache all diese Tests auch mit 127.0.0.1, daher ist die Netzwerkbandbreite kein Problem. 

Was könnte diese riesige Verlangsamung verursachen?  

UPDATE

Überprüfen Sie die geänderten Benchmark-Ergebnisse. Ich habe tatsächlich mit 10 GETs getestet und nicht mit 100, ich habe die Ergebnisse aktualisiert. 

66
Earlz

Was bei langsamen Webanfragen der Hauptschuldige ist, ist die Proxy-Eigenschaft. Wenn Sie diese Eigenschaft auf null setzen, bevor Sie die GetResponse-Methode aufrufen, überspringt die Abfrage den automatischen Proxy-Erkennungsschritt:

request.Proxy = null;
using (var response = (HttpWebResponse)request.GetResponse())
{
}

Es dauerte bis zu 7 Sekunden, bis der Proxy-Autodetect die Abfrage abfragte, bevor die Antwort zurückgegeben wurde. Es ist etwas ärgerlich, dass diese Eigenschaft standardmäßig für das HttpWebRequest-Objekt aktiviert ist.

165
James Roland

Dies kann mit der Tatsache zusammenhängen, dass Sie mehrere Verbindungen gleichzeitig öffnen. Die maximale Anzahl offener HTTP-Verbindungen ist standardmäßig auf zwei festgelegt. Versuchen Sie, dies Ihrer .config-Datei hinzuzufügen, und prüfen Sie, ob es hilfreich ist

<system.net>
  .......
  <connectionManagement>
    <add address="*" maxconnection="20"/>
  </connectionManagement>
</system.net>
20
Manu

Ich hatte ein ähnliches Problem mit einem VB.Net MVC-Projekt.
Auf meinem PC (Windows 7) dauerte es weniger als 1 Sekunde, um die Seitenanfragen zu treffen, aber auf dem Server (Windows Server 2008 R2) dauerte es 20 Sekunden für jede Seitenanforderung.

Ich habe versucht, den Proxy auf null zu setzen

  System.Net.WebRequest.DefaultWebProxy = Nothing
  request.Proxy = System.Net.WebRequest.DefaultWebProxy

Und die Konfigurationsdatei durch Hinzufügen ändern

 <system.net>
   .......
   <connectionManagement>
     <add address="*" maxconnection="20"/>
   </connectionManagement>
 </system.net>

Die langsamen Seitenanforderungszeiten auf dem Server wurden dadurch jedoch nicht verkürzt. Am Ende bestand die Lösung darin, die Option "Automatisch Einstellungen ermitteln" in den Optionen IE auf dem Server selbst zu deaktivieren. (Wählen Sie unter Extras -> Internetoptionen die Registerkarte Verbindungen. Klicken Sie auf die Schaltfläche LAN-Einstellungen.)

Unmittelbar nach dem Deaktivieren dieser Browseroption auf dem Server fielen alle Seitenanfragen von 20 Sekunden auf unter 1 Sekunde.

10
jamieb

Ich fing an, eine Verlangsamung ähnlich der OP in diesem Bereich zu beobachten, die durch die Erhöhung der MaxConnections etwas verbessert wurde.

ServicePointManager.DefaultConnectionLimit = 4;

Nach dem Aufbau dieser Anzahl von WebRequests kam es jedoch zu Verzögerungen.

In meinem Fall bestand das Problem darin, dass ich einen POST anrief und sich nicht um die Antwort kümmerte, also nicht aufnahm oder etwas damit anfing. Leider schwebte das WebRequest herum, bis das Zeitlimit überschritten wurde.

Die Lösung bestand darin, die Antwort abzuholen und sie 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();
7
tonycoupland

Verwenden Sie einen anderen Computer als localhost, und verwenden Sie dann WireShark , um zu sehen, was wirklich alles passiert.

Wie andere gesagt haben, kann es eine Reihe von Dingen sein. Ein Blick auf die Dinge auf der Ebene TCP sollte ein klares Bild ergeben.

3
kervin

Ich weiß nicht, wie genau ich diese Problemumgehung erreicht habe. Ich hatte noch keine Zeit für Nachforschungen, also liegt es an Ihnen. Es gibt einen Parameter, den ich so verwendet habe (im Konstruktor meiner Klasse, bevor das HTTPWebRequest-Objekt instanziiert wird)

System.Net.ServicePointManager.Expect100Continue = false;

Ich weiß nicht genau warum, aber jetzt sehen meine Anrufe ziemlich schneller aus.

3
user753746

Ich weiß, dass dies ein alter Thread ist, aber ich habe den ganzen Tag mit langsamen HttpWebRequest verloren, habe jede bereitgestellte Lösung ohne Erfolg ausprobiert. Jede Anfrage für eine Adresse dauerte mehr als eine Minute. 

Irgendwann war Problem mit meiner Antivirus Firewall (Eset) . Ich verwende eine Firewall mit interaktivem Modus, aber Eset war irgendwie ausgeschaltet vollständig. Das ließ die Anfrage für immer andauern. Nach Einschalten von Eset und Ausführen der Anforderung wird eine Aufforderung zur Firewall-Meldung angezeigt, und nach Bestätigung wird die Anforderung für weniger als eine Sekunde ausgeführt

Ich habe alle hier beschriebenen Lösungen ohne Erfolg ausprobiert, der Anruf dauerte etwa 5 Minuten.

Was war das Problem: Ich brauchte die gleiche Sitzung und natürlich die gleichen Cookies (Anfrage auf demselben Server), also Ich habe die Cookies von Request.Cookies in WebRequest.CookieContainer neu erstellt. Die Reaktionszeit betrug ca. 5 Minuten.

Meine Lösung: Kommentierte den Cookie-bezogenen Code aus und bam! Anruf dauerte weniger als eine Sekunde.

0
mihai_omega

Für mich bestand das Problem darin, dass ich LogMeIn Hamachi installiert hatte - ironischerweise, um das gleiche Programm aus der Ferne zu debuggen, das dann diese extreme Langsamkeit zeigte. 

Zu Ihrer Information, das Deaktivieren des Hamachi-Netzwerkadapters war nicht ausreichend, da der Windows-Dienst anscheinend den Adapter erneut aktiviert.

Auch das erneute Verbinden mit meinem Hamachi-Netzwerk hat das Problem nicht gelöst. Nur das Deaktivieren des Adapters (durch Deaktivieren des LogMeIn Hamachi-Windows-Dienstes) oder vermutlich das Deinstallieren von Hamachi haben das Problem für mich behoben.

Ist es möglich, HttpWebRequest aufzufordern, über einen bestimmten Netzwerkadapter auszugehen?

0
Craig Silver

Das hat für mich funktioniert:

<configuration>
  <system.net>
    <defaultProxy erabled="false"/>
  </system.net>
</configuration>

Credits: https://social.msdn.Microsoft.com/Forums/en-US/14844bfe-ad5b-4e5a-b6ef-4ff9a1a770f8/slow-httpwebrequest-the-rem-time-the-program-starts forum = ncl

0
mmmmmm