Parallel.Foreach 在幕后做了什么?

Ale*_*ade 6 .net c# parallel-processing foreach multithreading

所以我无法理解这里的概念。我有一个使用 Parallel 类和 Foreach 方法的方法。但我不明白的是,它是否会创建新线程以便更快地运行该函数?

让我们以此为例。我做了一个普通的 foreach 循环。

private static void DoSimpleWork()
        {
            foreach (var item in collection)
            {
                //DoWork();
            }
        }
Run Code Online (Sandbox Code Playgroud)

它将做的是,它将获取列表中的第一项,分配方法 DoWork(); 并等待它完成。简单,简单,有效。

现在.. 如果我这样做,我对三种情况感到好奇。

Parallel.ForEach(stringList, simpleString =>
            {
                DoMagic(simpleString);
            });
Run Code Online (Sandbox Code Playgroud)

这会将 Foreach 分成 4 个块吗?所以我认为正在发生的是它需要列表中的前 4 行,将每个字符串分配给每个“线程”(假设并行创建 4 个虚拟线程)完成工作,然后从该列表中的下 4 行开始?如果那是错误的,请纠正我我真的很想了解这是如何工作的。

然后我们有了这个。本质上是相同的,但有一个新参数

Parallel.ForEach(stringList, new ParallelOptions() { MaxDegreeOfParallelism = 32 }, simpleString =>
            {
                DoMagic(simpleString);
            });
Run Code Online (Sandbox Code Playgroud)

我很好奇的是这个

new ParallelOptions() { MaxDegreeOfParallelism = 32 }
Run Code Online (Sandbox Code Playgroud)

这是否意味着它将从该列表中获取前 32 个字符串(如果列表中有那么多字符串),然后执行与我上面所说的相同的操作?

而对于最后一个。

Task.Factory.StartNew(() =>
            {
                Parallel.ForEach(stringList, simpleString =>
                {
                    DoMagic(simpleString);
                });
            });
Run Code Online (Sandbox Code Playgroud)

这会创建一个新任务,将每个“块”分配给它自己的任务吗?

Ser*_*bov 2

不要将异步代码与并行代码混合在一起。任务用于异步操作 - 查询数据库、读取文件、等待一些计算成本相对较低操作,这样您的 UI 就不会被阻塞和无响应。

并行则不同。它专为 1) 多核系统和 2) 计算密集型操作而设计。我不会详细介绍它是如何工作的,此类信息可以在 MS 文档中找到。长话短说,并行。对于大多数人来说,它可能会自己决定运行什么、何时运行以及如何运行。它可能会违反您的参数,即 MaxDegreeOfParallelism 或其他参数。整个想法是提供最好的并行化,从而尽快完成您的操作。