2010-09-26 8 views
6

Hallo, ich habe eine Funktion, die URL-Parameter auf eine PHP-Datei auf einem Webserver und wartet auf eine Antwort aus der Datei Get passiert (dauert in der Regel 10 bis 20 Sekunden). Ich möchte dies in eine Schleife einfügen, weil ich diese Get-Anfragen an ungefähr 5 verschiedene php-Dateien gleichzeitig senden muss, aber wenn ich versuche, sie zu einer Schleife hinzuzufügen, lässt die Funktion die Schleife warten, bis die Datei die Antwort zurückgibt weiter zum nächsten.Asynchronous WebRequests mit C#

Gibt es eine Möglichkeit, dass ich alle 5 Anfragen auf einmal senden konnte, ohne auf die vorherige zu warten? (Ich dachte über das Threading, aber ach, ich habe es nie vorher berührt, ich weiß nicht, wo ich anfangen soll.)

+1

Threading ist der Weg Um dies zu erreichen, müssen Sie warten, bis alle 5 antworten, bevor Sie fortfahren. – ChrisF

Antwort

9

Anstelle der GetResponse() Methode könnten Sie die BeginGetResponse() verwenden, die ein nicht blockierender Anruf ist. Es dauert ein Rückruf, der dann das WebResponse Objekt behandeln kann, wenn es schließlich zurückkehrt. Das Beispiel im Link gibt Ihnen eine gute Vorstellung davon, wie der Haupt-Thread auf alle Antworten warten muss.

0

Verwenden Sie WebClient mit Async-Methoden.

Begin \ End ist schwieriger zu verwenden.

9

Hier sind zwei Ansätze, die die TPL verwendet.

Die erste wartet auf alle Anfragen zu vervollständigen, bevor Sie eines der Ergebnisse zugreifen

var runningTasks = new List<Task<string>>(); 

for (int ii = 0; ii <= 4; ii++) 
{ 
    var wreq = (HttpWebRequest)WebRequest.Create("..." + ii); 

    var taskResp = Task.Factory.FromAsync<WebResponse>(wreq.BeginGetResponse, 
                wreq.EndGetResponse, 
                null); 
    var taskResult = taskResp.ContinueWith(tsk => new StreamReader(tsk.Result.GetResponseStream()).ReadToEnd().Trim()); 
    runningTasks.Add(taskResult); 
} 

Task.WaitAll(runningTasks.ToArray()); 
IEnumerable<string> results = runningTasks.Select(tsk => tsk.Result); 

und die zweite etwas tut, mit jedem Ergebnis, wie es kommt:

for (int ii = 0; ii <= 4; ii++) 
{ 
    var wreq = (HttpWebRequest)WebRequest.Create("..." + ii); 

    var taskResp = Task.Factory.FromAsync<WebResponse>(wreq.BeginGetResponse, 
                wreq.EndGetResponse, 
                null); 
    taskResp.ContinueWith(tsk => new StreamReader(tsk.Result.GetResponseStream()).ReadToEnd().Trim()) 
      .ContinueWith((Task<string> trs) => 
       { 
        var result = trs.Result; 
        DoSomthingWithTheResult(result); 
       }); 
} 
+0

+1. Selbst wenn @ linuxuser27 Antwort nichts falsches hat, antwortet dieser besser auf die Frage und wird viel einfacher zu implementieren sein. –

+0

+1 In der Tat ist es. Die 'ContinueWith()' Methode ist a gute Idee – linuxuser27

+0

Und wie würde dies sich ändern, wenn ich einige Daten mit HTTP POST Anfrage mit BeginGetRequestStream/EndGetRequestSteam senden möchte? http://stackoverflow.com/questions/4190903 –