Versuch, mehrere HTTP-Anforderungen parallel auszuführen, aber von Windows (Registrierung) eingeschränkt

Ich entwickle eine Anwendung (winforms C # .NET 4.0), wo ich auf eine Nachschlagefunktionalität von einer dritten Partei durch eine einfache HTTP-Anfrage zugreife. Ich rufe eine URL mit einem Parameter auf, und im Gegenzug bekomme ich eine kleine Zeichenfolge mit dem Ergebnis der Suche. Einfach genug.

Die Herausforderung besteht jedoch darin, dass ich viele dieser Nachforschungen (einige tausend) machen muss, und ich möchte die benötigte Zeit begrenzen. Daher möchte ich Anfragen parallel abwickeln (zB 10-20). Dazu verwende ich einen ThreadPool, und die Kurzversion meines Codes sieht folgendermaßen aus:

public void startAsyncLookup(Action returnLookupResult) { this.returnLookupResult = returnLookupResult; foreach (string number in numbersToLookup) { ThreadPool.QueueUserWorkItem(lookupNumber, number); } } public void lookupNumber(Object threadContext) { string numberToLookup = (string)threadContext; string url = @"http://some.url.com/?number=" + numberToLookup; WebClient webClient = new WebClient(); Stream responseData = webClient.OpenRead(url); LookupResult lookupResult = parseLookupResult(responseData); returnLookupResult(lookupResult); } 

Ich fülle numbersToLookup (eine List ) von einem anderen Ort, rufe startAsyncLookup und startAsyncLookup es mit einer Callback-function returnLookupResult , um jedes Ergebnis zurückzugeben. Das funktioniert, aber ich habe festgestellt, dass ich nicht den gewünschten Durchsatz erziele.

Anfangs dachte ich, es könnte die dritte Partei sein, die ein schlechtes System am Ende hat, aber ich habe dies ausgeschlossen, indem ich versuchte, denselben Code von zwei verschiedenen Maschinen gleichzeitig auszuführen. Jeder der beiden dauerte so lange, wie einer es tat, also konnte ich das ausschließen.

Ein Kollege hat mir dann gesagt, dass dies eine Einschränkung in Windows sein könnte. Ich googelte ein bisschen und fand unter anderem diesen Beitrag, der besagt, dass Windows standardmäßig die Anzahl der gleichzeitigen Anfragen an denselben Webserver auf 4 für HTTP 1.0 und auf 2 für HTTP 1.1 begrenzt (für HTTP 1.1 entspricht dies tatsächlich der Spezifikation ( RFC2068)).

Derselbe Posten, der oben erwähnt wurde, bot auch eine Möglichkeit, diese Grenzen zu erhöhen. Durch Hinzufügen von zwei Registrierungswerten zu [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings] (MaxConnectionsPerServer und MaxConnectionsPer1_0Server) könnte ich dies selbst steuern.

Also, ich versuchte es (setzte beide auf 20), startete meinen Computer neu und versuchte, mein Programm erneut auszuführen. Leider schien es jedoch niemandem zu helfen. Ich behielt auch den Ressourcenmonitor ( siehe Screenshot ) im Auge, während ich meine Batch-Suche ausführte, und bemerkte, dass meine Anwendung (die mit dem ausgeschwärzten Titel) immer noch nur zwei TCP-Verbindungen verwendete.

Also, die Frage ist, warum funktioniert das nicht? Ist der Beitrag, mit dem ich verlinkt habe, mit den falschen Registrierungswerten verknüpft? Ist es vielleicht nicht mehr möglich in Windows “zu hacken” (ich bin auf Windows 7)?

Irgendwelche Ideen würden sehr geschätzt 🙂

Und für den Fall, dass sich jemand fragen sollte, habe ich auch verschiedene Einstellungen für MaxThreads auf ThreadPool (von 10 bis 100) probiert, und das schien meinen Durchsatz überhaupt nicht zu beeinflussen, also sollte das Problem auch nicht da sein.

Es ist eine Frage von ServicePoint . Welche bietet Verbindungsverwaltung für HTTP-Verbindungen. Die standardmäßige maximale Anzahl von gleichzeitigen Verbindungen, die von einem ServicePoint-Objekt zugelassen werden, ist 2. Wenn Sie sie erhöhen müssen, können Sie die ServicePointManager.DefaultConnectionLimit- Eigenschaft verwenden. Überprüfen Sie einfach den Link in MSDN, dort können Sie ein Beispiel sehen. Und stellen Sie den Wert ein, den Sie benötigen.

Für eine schnellere Referenz für jemanden. Um das Verbindungslimit pro Host zu erhöhen, können Sie dies in Ihrem Main () oder jederzeit tun, bevor Sie mit den HTTP-Anfragen beginnen.

  System.Net.ServicePointManager.DefaultConnectionLimit = 1000; //or some other number > 4 

Feuer und vergiss diese Methode von deiner Hauptmethode. Icognito Benutzer ist korrekt, nur 2 Threads dürfen gleichzeitig spielen.

 private static void openServicePoint() { ServicePointManager.UseNagleAlgorithm = true; ServicePointManager.Expect100Continue = true; ServicePointManager.CheckCertificateRevocationList = true; ServicePointManager.DefaultConnectionLimit = 10000; Uri MS = new Uri("http://My awesome web site"); ServicePoint servicePoint = ServicePointManager.FindServicePoint(MS); } 

Für Internet Explorer 8: Führen Sie den Registrierungseditor aus und navigieren Sie zum folgenden Schlüssel: HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Internet Explorer \ MAIN \ FeatureControl \ FEATURE_MAXCONNECTION SPERSERVER

und

HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Internet Explorer \ Haupt \ FeatureControl \ FEATURE_MAXCONNECTION SPER1_0SERVER

Wenn FEATURE_MAXCONNECTIONSPERSERVER und FEATURE_MAXCONNECTIONSPER1_0SERVER fehlen, erstellen Sie sie. Erstellen Sie jetzt DWORD-Wert namens iexplore.exe für beide Unterschlüssel (oben aufgeführt) und legen Sie ihren Wert auf 10 oder die gewünschte Zahl.