2009-10-21 8 views
0

J'ai une page qui doit combiner les données de quatre différents webrequests dans une seule liste d'éléments. Actuellement, je les exécute séquentiellement, en les ajoutant à une seule liste, puis en liant cette liste à mon répéteur.plusieurs webrequests de manière asynchrone dans asp.net?

Cependant, je voudrais pouvoir appeler ces quatre webrequests de façon asynchrone afin qu'ils puissent fonctionner simultanément et économiser du temps de chargement. Malheureusement, tous les tutoriels asynchrones et les articles que j'ai vus traitent d'une seule requête, en utilisant le gestionnaire fini pour continuer le traitement.

Comment puis-je effectuer les quatre (peut-être même augmenter!) Simultanément, en gardant à l'esprit que chaque résultat doit être introduit dans une seule liste?

merci beaucoup!

EDIT: exemple simplifié de ce que je fais:

var itm1 = Serialize(GetItems(url1)); 
list.AddRange(itm1); 
var itm2 = Serialize(GetItems(url2)); 
list.AddRange(itm2); 

string GetItems(string url) 
{ 
    var webRequest = WebRequest.Create(url) as HttpWebRequest; 
    var response = webRequest.GetResponse() as HttpWebResponse; 

    string retval; 
    using (var sr = new StreamReader(response.GetResponseStream())) 
    { retval = sr.ReadToEnd(); } 
    return retval; 
} 
+0

Avez-vous du code que vous pouvez publier pour nous montrer comment vous répondez actuellement à ces demandes? –

+0

ajouté un exemple simplifié de la façon dont je fais cela. Serialize() convertit simplement la chaîne json à la classe spécifiée pour la collection List – SelAromDotNet

+0

Je pense au lieu d'exécuter la requête de manière asynchrone avec BeginGetResponse, qui ne semble pas me sauver quoi que ce soit, j'ai besoin d'exécuter la méthode GetItems de façon asynchrone, que 4 demandes peuvent s'exécuter simultanément. Je pensais utiliser des threads avant et maintenant que je regarde mon problème, il semble que la meilleure chose à faire est d'émettre chaque GetItems sur un thread séparé, mais comment puis-je les synchroniser pour que l'application les exécute simultanément, puis agrège tous leurs résultats? – SelAromDotNet

Répondre

2

Cela devrait être très simple puisque vos données finale dépend du résultat de l'ensemble des quatre demandes.

Ce que vous pouvez faire est de créer 4 délégués asynchrones chacun pointant vers la méthode Web appropriée. Faites un BeginInvoke sur chacun d'eux. Et puis utilisez un WaitHandle pour attendre tout. Dans votre cas, il n'est pas nécessaire d'utiliser des rappels, car vous ne voulez pas continuer pendant le traitement des méthodes Web, mais plutôt attendre que toutes les méthodes Web aient fini d'être exécutées.

Seulement après l'exécution de toutes les méthodes Web, le code après l'exécution de l'instruction wait sera exécuté. Ici vous pouvez combiner les 4 résultats.

Voici un exemple de code I développé pour vous:

class Program 
    { 
     delegate string DelegateCallWebMethod(string arg1, string arg2); 

     static void Main(string[] args) 
     { 
      // Create a delegate list to point to the 4 web methods 
      // If the web methods have different signatures you can put them in a common method and call web methods from within 
      // If that is not possible you can have an List of DelegateCallWebMethod 
      DelegateCallWebMethod del = new DelegateCallWebMethod(CallWebMethod); 

      // Create list of IAsyncResults and WaitHandles 
      List<IAsyncResult> results = new List<IAsyncResult>(); 
      List<WaitHandle> waitHandles = new List<WaitHandle>(); 

      // Call the web methods asynchronously and store the results and waithandles for future use 
      for (int counter = 0; counter < 4;) 
      { 
       IAsyncResult result = del.BeginInvoke("Method ", (++counter).ToString(), null, null); 
       results.Add(result); 
       waitHandles.Add(result.AsyncWaitHandle); 
      } 

      // Make sure that further processing is halted until all the web methods are executed 
      WaitHandle.WaitAll(waitHandles.ToArray()); 

      // Get the web response 
      string webResponse = String.Empty; 
      foreach (IAsyncResult result in results) 
      { 
       DelegateCallWebMethod invokedDel = (result as AsyncResult).AsyncDelegate as DelegateCallWebMethod; 
       webResponse += invokedDel.EndInvoke(result); 
      } 
     } 


     // Web method or a class method that sends web requests 
     public static string CallWebMethod(string arg1, string arg2) 
     { 
      // Code that calls the web method and returns the result 

      return arg1 + " " + arg2 + " called\n"; 
     } 

    } 
1

Que diriez-vous de lancer chaque demande sur leur propre thread séparé, puis les résultats annexant à la liste?

+0

Je pense que créer des threads pour faire une telle opération est absolument NO-NO sauf si vous avez quelque chose de spécial à faire, par exemple changer la priorité des threads (par défaut, les threads sont en priorité normale). –

1

@Josh: En ce qui concerne votre question sur l'envoi de 4 (potentiellement plus) requêtes asynchrones et le suivi des réponses (par exemple pour alimenter dans une liste) . Vous pouvez écrire 4 requêtes et 4 gestionnaires de réponse, mais comme vous aurez potentiellement plus de requêtes, vous pouvez écrire une boucle asynchrone. Un classique pour une boucle est constitué d'un init, d'une condition et d'un incrément. Vous pouvez décomposer un classique pour une boucle en boucle while et être toujours équivalent. Ensuite, vous faites la boucle while dans une fonction récursive. Maintenant vous pouvez le rendre asynchrone. J'ai mis quelques exemples de scripts ici au http://asynchronous.me/. Dans votre cas, sélectionnez la boucle for dans les options. Si vous souhaitez que les requêtes soient envoyées en séquence, c'est-à-dire une requête après la réponse précédente (requête1, réponse1, requête2, réponse2, requête3, réponse3, etc.), choisissez Communication série (séquentielle), mais le code est un peu plus complexe. D'un autre côté, si vous ne vous souciez pas de l'ordre dans lequel les réponses sont reçues (ordre aléatoire), alors choisissez la communication Parallèle (ie concurrente), le code est plus intuitif. Dans les deux cas, chaque réponse sera associée à sa requête correspondante par un identifiant (un entier simple) afin que vous puissiez les suivre tous. Le site vous donnera un exemple de script. Les exemples sont écrits en JavaScript mais ils s'appliquent à n'importe quelle langue.Adaptez le script à votre langue et aux préférences de codage. Avec ce script, votre navigateur enverra 4 requêtes de manière asynchrone, et par l'identifiant vous pourrez suivre la requête à laquelle la réponse correspond. J'espère que cela t'aides./Thibaud Lopez Schneider

Questions connexes