关于.net:C#-Parallel.Invoke和Parallel.ForEach本质上是同一件事吗?

C# - Are Parallel.Invoke and Parallel.ForEach essentially the same thing?

"同一件事"是指这两个操作基本上完成相同的工作,只是归结为根据您要使用的操作调用哪个更方便? (即代表列表或要迭代的事物列表)?我一直在搜索MSDN,StackOverflow和各种随机文章,但我还没有找到明确的答案。

编辑:我应该更清楚一些;我问这两种方法是否做相同的事情,因为如果它们做不到,我想了解哪种方法会更有效。

示例:我有一个500个键值的列表。当前,我使用一个foreach循环(按序列方式)遍历列表并为每个项目执行工作。如果我想利用多个内核,我应该简单地使用Parallel.ForEach代替吗?
假设出于争论的目的,我有500个代表的数组来执行这500个任务-最终效果是调用Parallel.Invoke并给出500个代表列表的效果吗?

在此先感谢您!


Parallel.ForEach遍历元素列表,并且可以对数组的元素执行某些任务。

例如

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

Parallel.Invoke可以并行调用许多功能。

例如

1
2
3
4
Parallel.Invoke(
() => doSum(array),
() => doAvg(array),
() => doMedian(array));

从上面的示例中,您可以看到它们在功能上有所不同。 ForEach遍历元素的List并在每个元素上并行执行一个任务,而Invoke可以在单个元素上并行执行许多任务。


Parallel.Invoke和Parallel.ForEach(当用于执行Action时)的功能相同,尽管是的,人们特别希望集合是一个数组。请考虑以下示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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();

此代码在一次运行中产生此输出。通常,每次的输出顺序都不同。

0 5 1 6 2 7 3 8 4 9

0 1 2 4 5 6 7 8 9 3


我正试图找到一种措辞措辞的好方法;但它们不是一回事。

原因是,Invoke处理一个动作数组,而ForEach处理一个动作列表(特别是IEnumerable);列表在机制上与数组明显不同,尽管它们展现了相同的基本行为。

我无法说出实际的区别是因为我不知道,所以请不要接受这个答案(除非您真的想要!),但我希望它能使某人记忆犹新机制。

1个很好的问题。

编辑;我突然想到,还有另一个答案。调用可以处理动态的动作列表;但是Foreach可以使用Actions的通用IEnumerable,并且使您能够使用条件逻辑Action by Action;因此您可以在每个Foreach迭代中说出Action.Invoke()之前测试条件。