Frage

Ich habe eine Seite, die Daten von vier verschiedenen webrequests in eine einzige Liste von Elementen kombinieren muss. Derzeit bin ich diese nacheinander ausgeführt wird, zu einer einzigen Liste angehängt, dann zu meinem Repeater diese Liste zu binden.

Allerdings würde Ich mag diese vier webrequests asynchron aufrufen können, so dass sie gleichzeitig ausgeführt werden können und die Ladezeit sparen. Leider sind alle Asynchron-Tutorials und Artikel Ich habe mit einer einzigen Anfrage gesehen Angebot, das fertige Handler die Verarbeitung fortzusetzen.

Wie kann ich führe die vier (dies kann sogar erhöhen!) Gleichzeitig, wenn man bedenkt, dass jedes Ergebnis in eine einzige Liste zugeführt werden muss?

Vielen Dank!

EDIT: vereinfachtes Beispiel dafür, was ich tue:

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;
} 
War es hilfreich?

Lösung

Das sollte wirklich einfach sein, da Ihre endgültigen Daten über das Ergebnis aller vier Anforderungen abhängen.

Was Sie tun können, ist erstellen 4 Asynchron-Delegierten an der entsprechenden Web-Methode jeder zeigen. Führen Sie eine BeginInvoke auf allen von ihnen. Und dann einen Waithandle verwenden für alle zu warten. Es besteht keine Notwendigkeit Rückrufe zu verwenden, in Ihrem Fall, wie Sie wollen nicht weiter, während die Web-Methoden verarbeitet werden, sondern warten, bis alle Web-Methoden Ausführung beenden.

Erst nachdem alle Web-Methoden ausgeführt werden, wird der Code nach der Wartezeit-Anweisung ausführen. Hier können Sie die 4 Ergebnisse kombinieren.

Hier ist ein Beispielcode ich für Sie entwickelt:

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";
        }

    }

Andere Tipps

Wie wäre es jede Anforderung auf einem eigenen Thread starten und dann die Ergebnisse in die Liste anhängt?

können Sie diesen folgenden Code testen:

Parallel.Invoke (() =>                         {
                            // TODO Ihre Anfragen laufen ...                         });

Sie benötigen Parallel Erweiterungen verweisen: http://msdn.microsoft.com/en-us/concurrency/bb896007. aspx

@ Josh: In Bezug auf Ihre Frage zu 4 Senden (potentiell) asynchrone Anforderungen und der Verfolgung der Reaktionen (zum Beispiel in einer Liste zu füttern). Sie können 4 Anfragen und 4 Antwort-Handler schreiben, aber da Sie möglicherweise mehr Anfragen haben, können Sie eine asynchrone Schleife schreiben. Ein klassisches for-Schleife ist aus einem init, ein Zustand, und ein Inkrement vorgenommen. Sie können eine klassische for-Schleife in einer while-Schleife brechen und immer noch gleich. Dann sind Sie die while-Schleife in eine rekursive Funktion machen. Jetzt können Sie es asynchron machen. Ich habe ein paar Beispielskripte hier unter http://asynchronous.me/ . In Ihrem Fall, wählen Sie die for-Schleife in den Optionen. Wenn Sie die Anfragen gesendet werden sollen in der Folge wollen, dh eine Anfrage nach der vorherigen Antwort (Anfrage1, Reaktionszeit1, request2, response2, request3, response3, etc.) wählen, dann die serielle Kommunikation (dh sequentiell), aber der Code ist ein bisschen mehr kompliziert. Auf der anderen Seite, wenn Sie nicht über die Reihenfolge, in der sie kümmern werden die Antworten (zufällige Reihenfolge) empfangen wird, dann Parallele Kommunikation wählen (das heißt gleichzeitig), ist der Code intuitiver. In jedem Fall wird jede Antwort mit der entsprechenden Anforderung durch eine Kennung (ein einfaches integer) verknüpft werden, damit Sie den Überblick über sie alle halten können. Die Website wird Ihnen ein Beispielskript. Die Proben werden in JavaScript geschrieben, aber es ist für jede Sprache. Passen Sie das Skript an Ihre Sprache und Codierung Vorlieben. Mit diesem Skript wird Ihr Browser asynchron 4 Anfragen senden, und durch die Kennung können Sie den Überblick behalten, von denen die Antwort verlangen entspricht. Hoffe das hilft. / Thibaud Lopez Schneider

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top