質問

4つの異なるWebリクエストからのデータを単一のアイテムリストに結合する必要があるページがあります。現在、これらを順番に実行し、1つのリストに追加してから、そのリストをリピーターにバインドしています。

ただし、これら4つのwebrequestsを非同期で呼び出して、同時に実行してロード時間を節約できるようにしたいと思います。残念ながら、私が見たすべての非同期チュートリアルと記事は、単一のリクエストを処理し、finishedハンドラーを使用して処理を続行します。

各結果を単一のリストに入れる必要があることを念頭に置いて、4つ(これはさらに増えるかもしれません!)を同時に実行するにはどうすればよいですか?

どうもありがとう!

編集:私がやっていることの簡単な例:

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;
} 
役に立ちましたか?

解決

最終データは4つのリクエストすべての結果に依存するため、これは非常に簡単です。

できることは、それぞれが適切なWebメソッドを指す4つの非同期デリゲートを作成することです。それらすべてに対してBeginInvokeを実行します。そして、WaitHandleを使用してすべてを待ちます。 Webメソッドの処理中に続行するのではなく、すべてのWebメソッドの実行が完了するまで待機するため、コールバックを使用する必要はありません。

すべてのWebメソッドが実行された後にのみ、waitステートメントの後のコードが実行されます。ここで、4つの結果を組み合わせることができます。

これは、私が開発したサンプルコードです。

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

    }

他のヒント

各リクエストを独自のスレッドで起動し、結果をリストに追加する方法はどうですか?

次のコードをテストできます:

Parallel.Invoke(()=&gt;                         {
                            // TODOリクエストを実行します...                         });

参照並列拡張機能が必要です: http://msdn.microsoft.com/en-us/concurrency/bb896007。 aspx

@Josh:4つ(可能性としてはそれ以上)の非同期要求を送信し、応答を追跡する(たとえば、リストにフィードする)ことに関する質問について。 4つの要求と4つの応答ハンドラーを作成できますが、より多くの要求がある可能性があるため、非同期ループを作成できます。古典的なforループは、init、条件、および増分で構成されています。古典的なforループをwhileループに分解しても、同等のものを使用できます。次に、whileループを再帰関数に作成します。これで、非同期にすることができます。ここにいくつかのサンプルスクリプトを http://asynchronous.me/ に置きます。あなたの場合、オプションでforループを選択します。リクエストを順番に送信する場合、つまり、前のレスポンス(request1、response1、request2、response2、request3、response3など)の後に1つのリクエストを送信する場合は、シリアル通信(シーケンシャル)を選択しますが、コードはもう少し複雑。一方、応答が受信される順序(ランダムな順序)を気にしない場合は、並列通信(同時)を選択すると、コードはより直感的になります。どちらの場合でも、各応答は識別子(単純な整数)によって対応する要求に関連付けられるため、それらすべてを追跡できます。このサイトでは、サンプルスクリプトを提供します。サンプルはJavaScriptで記述されていますが、どの言語にも適用できます。スクリプトを言語とコーディング設定に適合させます。このスクリプトを使用すると、ブラウザーは4つの要求を非同期的に送信し、識別子によって、応答が対応する要求を追跡できます。お役に立てれば。 / Thibaud Lopez Schneider

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top