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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10867332/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 15:35:22  来源:igfitidea点击:

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

c#.netmultithreading.net-4.0parallel-processing

提问by Brad Gagne

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, StackOverflow, and various random articles but I have yet to find a clear answer for this.

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

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!

提前谢谢了!

采纳答案by Mayank

Parallel.ForEachgoes 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.Invokecan 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. ForEachiterates through a Listof elements and performs one taskon each elementin parallel, while Invokecan perform many tasksin parallel on a single element.

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

回答by Russ Clarke

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 的 Array,而 ForEach 适用于 Action 的 List(特别是 IEnumerable);列表在机制上与数组有很大不同,尽管它们公开了相同类型的基本行为。

I can't say whatthe 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 可以处理动态的 Actions 列表;但是 Foreach 可以使用 Generic IEnumerable of Actions 并让您能够使用条件逻辑,逐个操作;所以你可以在每次 Foreach 迭代中说 Action.Invoke() 之前测试一个条件。

回答by plukich

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(当用于执行操作时)功能相同,尽管有人特别希望集合是一个数组。考虑以下示例:

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 1 2 4 5 6 7 8 9 3

0 5 1 6 2 7 3 8 4 9

0 1 2 4 5 6 7 8 9 3