C# - Parallel.Invoke和Parallel.ForEach本质上是一回事吗?

时间:2022-08-28 07:42:54

And by "same thing" I mean do these two operations basically do the same work, and it just boils down to which one is more convenient to call based on what you have to work with? (i.e. a list of delegates or a list of things to iterate over)? I've been searching MSDN, *, and various random articles but I have yet to find a clear answer for this.

并且通过“同样的事情”我的意思是这两个操作基本上做同样的工作,它只是归结为哪个更方便根据你必须使用的工作进行调用? (即代表列表或迭代的事项列表)?我一直在搜索MSDN,*和各种随机文章,但我还没有找到一个明确的答案。

EDIT: I should have been clearer; I am asking if the two methods do the same thing because if they do not, I would like to understand which would be more efficient.

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

Example: I have a list of 500 key values. Currently I use a foreach loop that iterates through the list (serially) and performs work for each item. If I want to take advantage of multiple cores, should I simply use Parallel.ForEach instead? let's say for arguments's sake that I had an array of 500 delegates for those 500 tasks - would the net effect be any different calling Parallel.Invoke and giving it a list of 500 delegates?

示例:我有500个键值的列表。目前我使用foreach循环遍历列表(连续)并执行每个项目的工作。如果我想利用多个内核,我应该简单地使用Parallel.ForEach吗?让我们说为了参数的缘故,我为这500个任务提供了500个代表的数组 - 是否会产生任何不同的调用Parallel.Invoke,给它一个500个代表的列表?

Many thanks in advance!

提前谢谢了!

3 个解决方案

#1


20  

Parallel.ForEach goes through the list of elements and can perform some task on the elements of the array.

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

eg.

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

Parallel.Invoke can invoke many functions in parallel.

Parallel.Invoke可以并行调用许多函数。

eg.

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

As from the example above, you can see that they are different in functionality. ForEach iterates through a List of elements and performs one task on each element in parallel, while Invoke can perform many tasks in parallel on a single element.

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

#2


7  

Parallel.Invoke and Parallel.ForEach (when used to execute Actions) function the same, although yes one specifically wants the collection to be an Array. Consider the following sample:

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

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();

This code produces this output on one Run. It's output is generally in a different order every time.

此代码在一次运行中生成此输出。它的输出通常每次都以不同的顺序排列。

0 5 1 6 2 7 3 8 4 9

0 5 1 6 2 7 3 8 4 9

0 1 2 4 5 6 7 8 9 3

0 1 2 4 5 6 7 8 9 3

#3


0  

I'm trying to find a good way of phrasing it; but they are not the same thing.

我正试图找到一种好方法来表达它;但他们不是一回事。

The reason is, Invoke works on an Array of Action and ForEach works on a List (specifically an IEnumerable) of Action; Lists are significantly different to Arrays in mechanics although they expose the same sort of basic behaviour.

原因是,Invoke适用于Action of Action,而ForEach适用于Action的List(特别是IEnumerable);列表与力学中的数组明显不同,尽管它们暴露了相同类型的基本行为。

I can't say what the difference actually entails because I don't know, so please don't accept this an an answer (unless you really want too!) but I hope it jogs someones memory as to the mechanisms.

我不能说实际上有什么区别因为我不知道,所以请不要接受这个答案(除非你真的也想要!)但是我希望它能慢慢记住机制的内存。

+1 for a good question too.

+1也是一个好问题。

Edit; It just occurred to me that there is another answer too; Invoke can work on a dynamic list of Actions; but Foreach can work with a Generic IEnumerable of Actions and gives you the ability to use conditional logic, Action by Action; so you could test a condition before saying Action.Invoke() in each Foreach iteration.

编辑;我突然想到还有另一个答案; Invoke可以在动态动作列表上工作;但Foreach可以使用Generic IEnumerable of Actions,并使您能够使用条件逻辑,Action by Action;所以你可以在每个Foreach迭代中说Action.Invoke()之前测试一个条件。

#1


20  

Parallel.ForEach goes through the list of elements and can perform some task on the elements of the array.

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

eg.

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

Parallel.Invoke can invoke many functions in parallel.

Parallel.Invoke可以并行调用许多函数。

eg.

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

As from the example above, you can see that they are different in functionality. ForEach iterates through a List of elements and performs one task on each element in parallel, while Invoke can perform many tasks in parallel on a single element.

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

#2


7  

Parallel.Invoke and Parallel.ForEach (when used to execute Actions) function the same, although yes one specifically wants the collection to be an Array. Consider the following sample:

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

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();

This code produces this output on one Run. It's output is generally in a different order every time.

此代码在一次运行中生成此输出。它的输出通常每次都以不同的顺序排列。

0 5 1 6 2 7 3 8 4 9

0 5 1 6 2 7 3 8 4 9

0 1 2 4 5 6 7 8 9 3

0 1 2 4 5 6 7 8 9 3

#3


0  

I'm trying to find a good way of phrasing it; but they are not the same thing.

我正试图找到一种好方法来表达它;但他们不是一回事。

The reason is, Invoke works on an Array of Action and ForEach works on a List (specifically an IEnumerable) of Action; Lists are significantly different to Arrays in mechanics although they expose the same sort of basic behaviour.

原因是,Invoke适用于Action of Action,而ForEach适用于Action的List(特别是IEnumerable);列表与力学中的数组明显不同,尽管它们暴露了相同类型的基本行为。

I can't say what the difference actually entails because I don't know, so please don't accept this an an answer (unless you really want too!) but I hope it jogs someones memory as to the mechanisms.

我不能说实际上有什么区别因为我不知道,所以请不要接受这个答案(除非你真的也想要!)但是我希望它能慢慢记住机制的内存。

+1 for a good question too.

+1也是一个好问题。

Edit; It just occurred to me that there is another answer too; Invoke can work on a dynamic list of Actions; but Foreach can work with a Generic IEnumerable of Actions and gives you the ability to use conditional logic, Action by Action; so you could test a condition before saying Action.Invoke() in each Foreach iteration.

编辑;我突然想到还有另一个答案; Invoke可以在动态动作列表上工作;但Foreach可以使用Generic IEnumerable of Actions,并使您能够使用条件逻辑,Action by Action;所以你可以在每个Foreach迭代中说Action.Invoke()之前测试一个条件。