web-dev-qa-db-ja.com

C#-Parallel.InvokeとParallel.ForEachは本質的に同じものですか?

そして、「同じこと」とは、これら2つの操作が基本的に同じ作業を行うことを意味します。つまり、作業対象に基づいて、どちらを呼び出すのが便利かということです。 (つまり、デリゲートのリストまたは反復するもののリスト)?私はMSDN、StackOverflow、およびさまざまなランダムな記事を検索してきましたが、これに対する明確な答えはまだ見つかりません。

編集:もっと明確にすべきだった; 2つの方法が同じことをするかどうかを尋ねています。そうでない場合は、どちらがより効率的かを理解したいと思います。

例:500個のキー値のリストがあります。現在、リストを(連続して)繰り返し、各項目の作業を実行するforeachループを使用しています。複数のコアを利用したい場合は、代わりにParallel.ForEachを使用する必要がありますか?議論のために、これらの500のタスクに対して500のデリゲートの配列があったとしましょう-正味の効果は、Parallel.Invokeを呼び出して、500のデリゲートのリストを与えることとは異なるでしょうか?

よろしくお願いします!

19
Brad Gagne

Parallel.ForEachは要素のリストを調べ、配列の要素に対していくつかのタスクを実行できます。

例えば。

Parallel.ForEach(val, (array) => Sum(array));

Parallel.Invokeは多くの関数を並行して呼び出すことができます。

例えば。

Parallel.Invoke(
() => doSum(array),
() => doAvg(array),
() => doMedian(array));

上記の例からわかるように、機能が異なることがわかります。 ForEachListの要素を反復処理し、1つのタスク各要素で実行します。並列、Invoke単一要素多くのタスクを並列に実行できます。

25
Mayank

Parallel.InvokeとParallel.ForEach(アクションの実行に使用される場合)は同じように機能しますが、コレクションを配列にする必要があります。次のサンプルについて考えてみます。

List<Action> actionsList = new List<Action>
            {
                () => Console.WriteLine("0"),
                () => Console.WriteLine("1"),
                () => Console.WriteLine("2"),
                () => Console.WriteLine("3"),
                () => Console.WriteLine("4"),
                () => Console.WriteLine("5"),
                () => Console.WriteLine("6"),
                () => Console.WriteLine("7"),
                () => Console.WriteLine("8"),
                () => Console.WriteLine("9"),
            };

            Parallel.ForEach<Action>(actionsList, ( o => o() ));

            Console.WriteLine();

            Action[] actionsArray = new Action[]
            {
                () => Console.WriteLine("0"),
                () => Console.WriteLine("1"),
                () => Console.WriteLine("2"),
                () => Console.WriteLine("3"),
                () => Console.WriteLine("4"),
                () => Console.WriteLine("5"),
                () => Console.WriteLine("6"),
                () => Console.WriteLine("7"),
                () => Console.WriteLine("8"),
                () => Console.WriteLine("9"),
            };

            Parallel.Invoke(actionsArray);

            Console.ReadKey();

このコードは、1回の実行でこの出力を生成します。通常、出力の順序は毎回異なります。

0 5 1 6 2 7 3 8 4 9

0 1 2 4 5 6 7 8 9 3

10
plukich

私はそれを言い表す良い方法を見つけようとしています。しかし、それらは同じものではありません。

その理由は、Invokeはアクションの配列で機能し、ForEachはアクションのリスト(具体的にはIEnumerable)で機能するためです。リストは、同じ種類の基本的な動作を公開しますが、力学の配列とは大幅に異なります。

言うことはできませんwhatわからないので実際に違いが生じるので、これを答えとして受け入れないでください(あなたが本当に望んでいない限り!)が、誰かの記憶を揺さぶることを願っていますメカニズムに。

良い質問にも+1。

編集;別の答えもあることに気づきました。 Invokeは、アクションの動的リストで機能します。ただし、Foreachはアクションの汎用IEnumerableを操作でき、条件付きロジックであるアクションごとのロジックを使用できます。したがって、Foreachの各反復でAction.Invoke()と言う前に、条件をテストできます。

0
Russ Clarke