0

後でサーバーに送信される何千ものリクエストを作成するタスクがあります。サーバーは要求ごとに応答を返し、その応答は出力ファイルに 1 行ずつダンプされます。

擬似コードは次のようになります。

//requests contains thousands of requests to be sent to the server
string[] requests = GetRequestsString();


foreach(string request in requests)
{
   string response = MakeWebRequest(request);
   ParseandDump(response);
}

ご覧のとおり、サーブはリクエストを 1 つずつ処理しています。このプロセス全体を高速化したい。問題のサーバーは、一度に複数の要求を処理できます。マルチスレッドを適用して、一度に4つのリクエストをサーバーに送信し、同じスレッドでレスポンスをダンプしたいとします。

可能なアプローチへのポインタを教えてください。

4

3 に答える 3

2

Task.NET 4.0 と新しい toyを利用できHttpClientます。以下のサンプル コードは、リクエストを並行して送信し、次に を使用して同じスレッドでレスポンスをダンプする方法を示していますContinueWith

var httpClient = new HttpClient();
var tasks = requests.Select(r => httpClient.GetStringAsync(r).ContinueWith(t =>
            {
                ParseandDump(t.Result);
            }));

タスクは内部ThreadPoolで使用されるため、使用するスレッド数を指定する必要はなくThreadPool、最適化された方法でこれを管理します。

于 2013-02-05T16:35:41.763 に答える
1

最も簡単な方法は、次のように使用することParallel.ForEachです。

string[] requests = GetRequestsString();
Parallel.ForEach(requests, request => ParseandDump(MakeWebRequest(request)));

を使用するには、.NET Framework 4.0 以上が必要ですParallel

于 2013-02-05T16:40:14.780 に答える
0

これは、消費者-生産者-パターンで実行できると思います。多くの並列 WebRequest とダンプ スレッドの間の共有リソースとしてConcurrentQueue(名前空間から) を使用できます。System.Collections.Concurrent

擬似コードは次のようになります。

var requests = GetRequestsString();
var queue = new ConcurrentQueue<string>();

Task.Factory.StartNew(() => 
{
    Parallel.ForEach(requests , currentRequest =>
    {
        queue.Enqueue(MakeWebRequest(request));
    }
});

Task.Factory.StartNew(() =>
{
    while (true)
    {        
       string response;
       if (queue.TryDequeue(out response))
       {
          ParseandDump(response);
       }

    }
  });

BlockingCollection受信リクエストの終了を通知するためにスレッドを同期する方法によっては、より良いサービスを提供するかもしれません。

于 2013-02-05T16:36:31.573 に答える