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.

構文が正しいかどうかを無視して、これらは同等ですか?

それらは同じ結果を生み出しますか?そうでない場合、なぜですか?そしてどちらが好ましいですか?

4

3 に答える 3

5

説明したコードとユース ケースでは、2 つのアプローチは本質的に同等です。

Parallel.ForEach は、入力範囲を複数のタスクに分割する必要がある場合に役立ちます (ここでは適用できません)。または、いくつかの独立した並列操作の結果のマージを簡単に同期できます (おそらくここで適用できますか?)。

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

于 2012-07-09T00:45:27.330 に答える
1

2 つのコードの間では、Parallel.ForEach()複数のアイテムをTask1 つの で次々に処理するため、より効率的になります。

ただし、どちらも が許可する限り多くのスレッドを使用するためThreadPool、この場合はお勧めできません。これThreadPoolは、非常に短い CPU バウンドTaskの s がある場合に、 が最適なスレッド数を推測するのに優れているためです。これは、ここでは当てはまりません。

そのため、最良のオプションは、並列度を手動で小さな数に制限することだと思います (最良の結果が得られる数を調べるために測定する必要があります)。

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 をProxy使用していて、タスクベースの非同期パターン (TAP) をサポートするように更新した場合は、 TPL Dataflow を使用して、コードをさらに効率的に実行します。

var actionBlock = new ActionBlock<ServiceMemberBase>(
    async member =>
    {
        var result = await Proxy.InvokeAsync(member);
        //...
        //Do stuff with the result
        //...
    }
    new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 10 });
于 2012-07-09T06:30:13.763 に答える
1

出力を熟考したり見たりしなければ、2つが同じかどうかははっきりと言えませんでした。しかし、それらがそれほど異なるかどうかは疑問です。どちらが優れているかという質問は、シナリオに応じて主観的です。どちらが好ましいかを答えるには、やはり非常に主観的です。あなたが提供したシナリオでは、Parallel.ForEachを読むことができるので、私は Parallel.ForEach を好むと思いますが、開発チームが Parallel ライブラリに慣れていない場合は、2 番目のバージョンが 1 つです。行く。

于 2012-07-09T01:02:23.167 に答える