HttpWebRequest - kann ich mehrere Aufrufe gleichzeitig aus mehreren Threads ausführen

8

Ich verwende HttpWebRequest, um Anforderungen für Webseiten zu erstellen, als sie zu analysieren.

%Vor%

dann, wenn mehr Threads

aufrufen %Vor%

zur gleichen Zeit, sollte jeder seine eigene Antwort erhalten oder ist es für Thread 2 möglich, die Antwort für Thread7 zum Beispiel zu bekommen?

Obs: Die Adresse ist für alle Threads gleich, nur die POST-Parameter ändern sich

%Vor%

So benutze ich die Methode:

%Vor%

Bitte sagen Sie mir, wo ich mich irre? Wie sollte ich den Code ändern? Bitte helfen Sie mir, ich kann nichts hilfreiches im Internet finden!

    
Ryan 19.02.2011, 14:22
quelle

2 Antworten

18

Um ehrlich zu sein, glaube ich nicht, dass das Multi-Threading, das Sie versuchen, Ihnen irgendwelche Performance-Gewinne bringen wird. Und da es keinen Schwellenwert für die Anzahl der Threads gibt, die Sie hier erstellen könnten, besteht das Potenzial für schlechtere Leistung als bei einem sequenziellen Vorgang mit nur einem Thread.

Die ideale Situation ist, dass Sie einen asynchronen Arbeitsablauf haben. Wo ist Ihre Schleife etwa so:

GetAsyncRequest MakeAsyncRequest ReceiveResponseAsync ProzessResponse WaitForAllRequestProcessingToComplete (optional)

So dass das Ergebnis jedes Schrittes in den nächsten (wenn es ein Ergebnis gibt) und den nächsten einfügt. Und Sie verarbeiten die Antworten, sobald Sie sie erhalten, anstatt alle Antworten zu kumulieren (zu verbinden / zu blockieren), bevor Sie mit der Verarbeitung fortfahren. Diese Art der Sache kann leicht mit Tasks und ContinueWith in .NET 4.0 getan werden und sehen, dass Sie .NET 4.0 verwenden Ich würde vorschlagen, dass Sie es tun, wie oben beschrieben.

Wenn Sie Ihre Verarbeitung jedoch nicht in einen asynchronen Workflow konvertieren können, dann ...

Die unten gezeigte Methode ist die Methode, die den Aufruf an die URL sendet und eine Antwort zurückgibt. Die Methode verwendet Async-Aufrufe, blockiert jedoch, da Ihr Design so aussieht.

%Vor%

Sie würden es so nennen:

%Vor%

Sehen Sie, ob das für Sie funktioniert.

Wenn Sie Multithread-Funktionen wirklich benötigen, müssen Sie natürlich die Performance-Vorteile messen, da die Site in der Lage sein muss, den Ansturm von Anfragen zu bewältigen, und auf dem Client der Die Kosten für das Erstellen von Threads können nur dazu führen, dass einige I / O-gebundene Aufgaben zu kostspielig werden und ohne Leistungssteigerung enden.

Außerdem werden Sie, ohne das DefaultConnectionLimit im ServicePointManager anzupassen, niemals mehr als zwei Threads erhalten, da Sie gegen eine Domain arbeiten und das Standardlimit 2 Threads pro Domain beträgt.

Ich würde bei dem Code bleiben, den ich vorgestellt habe, und wenn es nur ein Performance-Problem gibt, würde ich es anders machen.

Bearbeiten: Wenn Sie Async-E / A verwenden, verwenden Sie keine Worker-Threads, sondern I / O-Threads. Also im Grunde wollen Sie nicht QueueUserWorkItem (um Threads zu erstellen) oder Sie erstellen nicht Threads selbst.

Der Code, den ich vorgestellt habe, benutzt Async I / O und wenn mehrere Anfragen simultan und so schnell wie möglich ausgeführt werden sollen.

Die for-Schleife (in der zweiten Code-Liste) wird fast sofort beendet, obwohl sie im Beispiel 100 Iterationen durchläuft und dann wartet, bis alle E / A-Anforderungen beendet sind. Der ThreadPool und das Betriebssystem werden die I / O-Jobs so schnell und so schnell wie möglich ausführen. Da diese Jobs E / A-gebunden sind, sehen Sie auch nicht, dass Ihre CPU-Auslastung ansteigt (es sei denn, Sie arbeiten später CPU-gebunden).

Spielen Sie einfach mit dem ServiceManager.DefaultConnectionLimit, um bei Bedarf mehr Beschleunigung zu erhalten. Beachten Sie, dass sich dies auch auf den Dienst (den Server) auswirkt, da der Server, den Sie aufrufen, stark ausgelastet ist, wenn Sie viele gleichzeitige Anforderungen stellen, und das ist möglicherweise nicht erwünscht. Es ist also eine Balance, die Sie treffen müssen.

Nach dem Aufruf von Task.WaitAll können Sie die Tasksammlung iterieren und die Ergebnisse der einzelnen Tasks mit der in der Kommentarzeile in der Codeauflistung angegebenen Syntax abrufen.

    
Shiv Kumar 19.02.2011, 18:58
quelle
0

Es hängt davon ab, wie Sie es tun. Und wenn Sie Antworten von einem Thread in einem anderen erhalten, tun Sie es falsch.

Vielleicht wäre es eine gute Möglichkeit, eine Arbeitseinheit zu entwickeln, die Ihre URL annimmt und Informationen als Parameter veröffentlicht. Es wird dann eine neue HttpWebRequest-Instanz auslösen, die Antwort behandeln und diese Antwort (mit allen notwendigen Änderungen / Bereinigungen) zurückgeben.

Diese Arbeitseinheiten könnten dann in getrennten Threads gestartet und die Antworten gesammelt werden. Sobald alle Threads abgeschlossen sind, können Sie die Ergebnisse verarbeiten.

    
rvxnet 19.02.2011 14:29
quelle