2010-09-26 6 views
6

Salut j'ai une fonction qui passe url Obtenir des paramètres à un fichier php sur un serveur web et attend une réponse du fichier (prend normalement 10-20 secondes). Je veux mettre ceci dans une boucle parce que je dois envoyer ces demandes de Get à environ 5 fichiers php différents à la fois mais quand j'essaye de l'ajouter à une boucle, la fonction attend que le fichier retourne la réponse avant que ça ne passe sur le prochain.WebRequests asynchrones utilisant C#

public string HttpGet(string URI, string Parameters) 
    { 
     HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URI + Parameters); 

     HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 
     StreamReader resStream = new StreamReader(response.GetResponseStream()); 
      return resStream.ReadToEnd().Trim(); 
    } 

    private void SendCommand() 
    { 
     for(int i = 0; i <= 4; i++) 
     { 
      AddRTB(HttpGet(url, paramater)); 
     } 
    } 

Y at-il un moyen que je puisse envoyer les 5 demandes à la fois sans attendre la fin de la précédente? (Je pensais à l'enfiler, mais hélas je ne l'ai jamais touché auparavant, je ne sais pas par où commencer.)

+1

Threading est la manière pour y arriver, mais vous devrez attendre que tous les 5 répondent avant de continuer. – ChrisF

Répondre

9

Au lieu d'utiliser la méthode GetResponse(), vous pouvez utiliser le BeginGetResponse() qui est un appel non bloquant. Il prend un rappel qui peut ensuite gérer l'objet WebResponse quand il revient finalement. L'exemple dans le lien vous donnera une bonne idée de la manière dont le thread principal attendra que toutes les réponses soient renvoyées.

0

Utilisez WebClient avec des méthodes asynchrones.

Début \ Fin est plus difficile à utiliser.

9

Voici deux approches qui utilisent le TPL.

Le premier attend toutes les demandes de compléter avant d'accéder à l'un des résultats

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

et le second fait quelque chose avec chaque résultat comme il vient:

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.) Même si la réponse @ linuxuser27 n'a rien de faux, celle-ci répondra mieux à la question et sera beaucoup plus facile à implémenter –

+0

+1 En effet, la méthode 'ContinueWith()' est un bonne idée – linuxuser27

+0

Et comment cela changerait-il si j'ai besoin d'envoyer des données avec une requête HTTP POST avec BeginGetRequestStream/EndGetRequestSteam? http://stackoverflow.com/questions/4190903 –

Questions connexes