2012-07-09 10 views
7

TPLを使い始めたばかりで、Webサービスへの複数の呼び出しを並行して実行したいと考えています。私が集めることから、私はこれを行う2つの方法を見ます。タスク並列ライブラリを使用する方が良いでしょう

どちらかParallel.ForEach

List<ServiceMemberBase> list = new List<ServiceMemberBase>(); //Take list from somewhere. 
     Parallel.ForEach(list, member => 
      { 
       var result = Proxy.Invoke(member); 
       //... 
       //Do stuff with the result 
       //... 
      }); 

またはTask<T>

List<ServiceMemberBase> list = new List<ServiceMemberBase>(); //Take list from somewhere. 
     ForEach(var member in list) 
     { 
      Task<MemberResult>.Factory.StartNew(() => proxy.Invoke(member)); 
     } 

     //Wait for all tasks to finish. 
     //Process the result objects. 

構文が正しいかどう無視し、equivilantするには、これらは何ですか?

同じ結果が得られますか?そうでない場合、なぜですか?それは好ましいですか?

答えて

5

あなたが議論するコードとユースケースについては、2つのアプローチは本質的に同等です。

Parallel.ForEachは、入力範囲をいくつかのタスク(ここでは適用不可)に分割する必要がある場合や、複数の独立した並列処理の結果のマージを簡単にする場合に便利です(ここではおそらく適用可能でしょうか?

いずれにしても、Parallel.ForEachの場合、手動でタスクを開始する場合は手動で同期を管理する必要がありますが、手動で同期を完了する必要はありません。この場合はおそらくTask.WaitAll(...)のようなものを使用します。

+0

ありがとうございます。私はParallel.ForEachを使用して終了しました。私たちの生産である16コアマシンでは、応答時間が約25%向上しました。私は、ほとんどの利得がパラレルデータ処理であり、Webサービス自体への並列呼び出しではないと推測しています。 –

1

出力を反映したり表示したりすることなく、2つが同じかどうかは確かに言えませんでした。しかし、彼らがそれほど違っているのであれば、私は疑うだろう。シナリオによっては、どちらが良いかに関する質問が主観的です。あなたが提供したシナリオでは、Parallel.ForEach を読むことができます。を読むことができますが、開発チームがParallelライブラリに使用されていない場合、2番目のバージョンは次のとおりです。行く人。

1

Parallel.ForEach()の2つのコードの間で、1つのTaskで複数のアイテムを1つずつ処理するので、効率的になります。

しかし、両方のスレッドは、ThreadPoolのように多くのスレッドを使用しますが、この場合はお勧めできません。これは、ThreadPoolが、非常に短いCPUバウンドのTaskを持っている場合に、最適なスレッド数を推測するのがうまくいくためです。でも

List<ServiceMemberBase> list = …; //Take list from somewhere. 
Parallel.ForEach(list, new ParallelOptions { MaxDegreeOfParallelism = 10 }, 
member => 
{ 
    var result = Proxy.Invoke(member); 
    //... 
    //Do stuff with the result 
    //... 
}); 

そのため、私は最良の選択肢を手動で少数(あなたは数が最良の結果を与えるかを調べるために測定する必要があります)に並列度を制限することだと思います非効率的にWebサービス呼び出しを実行できる場合はより効率的です。 C#5を使用していないかぎり、C#5で作業をしていて、タスクベースの非同期パターン(TAP)をサポートするようにProxyを更新した場合は、 TPLデータフローを使用してコードをさらに効率的に実行できます。

var actionBlock = new ActionBlock<ServiceMemberBase>(
    async member => 
    { 
     var result = await Proxy.InvokeAsync(member); 
     //... 
     //Do stuff with the result 
     //... 
    } 
    new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 10 }); 
関連する問題