当前位置: 首页 > 知识库问答 >
问题:

平行之间的差异。ForEach和Wait ForEachAsync

燕航
2023-03-14

在任何情况下(反之亦然),是否有任何理由选择并行的。对于每个而不是等待ForEachAsync?或者它们实际上是相同的?

await collection.ForEachAsync( m => { m.DoSomething(); } );

VS公司

Parallel.ForEach( collection, m => { m.DoSomething(); } );

共有3个答案

景翰音
2023-03-14

在任何情况下(反之亦然),是否有任何理由选择并行。Foreach而不是等待ForEachAsync?

并行。ForEach用于同步代码。它的委托必须是同步的,并且是同步调用的。

ForEachAsync不是标准算法。有几种不同的实现,但通常它们试图混合异步和并行。他们必须放弃并行的一些自我平衡方面。ForEach。绝大多数代码不需要ForEachAsync;大多数代码要么是异步的,要么是并行的。

羿宏硕
2023-03-14

这完全取决于线程,假设您有以下类

public class person
    {
        public int ID { get; set; }
        public string Name { get; set; }
    }

这是你的主要课程

List<person> persons = new List<person>()
            {
                new person{ ID = 1,Name="Ali"}
                ,new person{ ID = 2,Name="Gorge"}
                ,new person{ ID = 3,Name="Alex"}
                ,new person{ ID = 4,Name="Liz"}
                ,new person{ ID = 5,Name="Scott"}
                ,new person{ ID = 6,Name="Abby"}
                ,new person{ ID = 7,Name="Sarah"}
            };

            Parallel.ForEach(persons, (p) =>
            {
                Console.WriteLine($"Id : {p.ID} ,Name : {p.Name}");
            });

在这里,我再次运行相同的代码,但得到了不同的结果

因为线程的原因,编译器划分为线程数,每个列表运行分配给它的项目,下面的图片显示了不同的线程

但是当您运行以下代码时

List<person> persons = new List<person>()
            {
                new person{ ID = 1,Name="Ali"}
                ,new person{ ID = 2,Name="Gorge"}
                ,new person{ ID = 3,Name="Alex"}
                ,new person{ ID = 4,Name="Liz"}
                ,new person{ ID = 5,Name="Scott"}
                ,new person{ ID = 6,Name="Abby"}
                ,new person{ ID = 7,Name="Sarah"}
            };

            await persons.ForEachAsync(async p => Console.WriteLine($"Id : {p.ID} ,Name : {p.Name}"));

如图所示,您只能获得一个线程

此外,数据打印将始终按列表的相同顺序运行

我希望这个答案能解释这种差异!

韩景辉
2023-03-14

它们根本不是“几乎相同的”。

当您使用并行类中的函数时,例如并行。Foreach()您正在调用一些操作,其中该操作被分解为多个较小的操作,每个操作在不同的线程上执行(也称为多线程)。

另一方面,ForEachAsync不一定是多线程的。这是异步操作,异步操作不是多线程操作(它们可以是,但不一定是,这取决于实现)。

我强烈建议阅读下面的帖子,它会更详细地介绍这个话题。

至于你的问题

有什么理由在任何情况下都选择并行。Foreach而不是等待ForEachAsync

答案肯定是这样做是有原因的,但是为了确定你会使用哪种场景,你必须同时理解它们。

下面是一个简单的例子:

您有一个对象的集合,并且希望对其进行迭代并执行某种操作。您是否关心这些操作的发生顺序?如果是,请不要使用并行。ForEach(),因为无法保证调用它们的顺序(由于其多线程性质)。

编辑:

在您的示例中,这完全取决于集合中有多少项,以及DoThings()的流程繁重程度。

这是因为并行。ForEach()不是免费的。需要进行权衡。设置多线程环境需要时间,如果集合很小和/或DoSomething()不需要太长时间,则使用单线程异步操作可以更好(通常更快)地设置这些线程。

另一方面,如果收集量很大和/或DoSomething()是一项流程繁重的任务,则并行。ForEach()无疑将是性能最好的选项。

 类似资料:
  • 我一直认为和完全相同,因此可以互换使用。今天,当我试图在我的共享服务器上安装pylibmc(一个绑定到memcached的python)时,使用给了我错误,但没有。我想解释一下原因。 libmemcache是pylibmc的一个要求。我在我的主目录下安装了libmemcache,因为我在服务器上没有根。因此,要安装pylibmc,我需要确保安装脚本知道在哪里可以找到libmemcache。 当执行

  • 问题内容: 很快就有两个相等运算符:double equals( )和Triple equals( ),两者之间有什么区别? 问题答案: 简而言之: 操作员检查其实例值是否相等, 操作员检查引用是否指向同一实例, 长答案: 类是引用类型,可能有多个常量和变量在幕后引用类的同一单个实例。类引用保留在运行时堆栈(RTS)中,其实例保留在内存的堆区域中。当您控制平等时, 这意味着它们的实例是否彼此相等。

  • 我编写了一个简单的脚本,它接受任意数量的参数来演示< code>$@和< code>$*之间的区别: 在我做的 CLI 上 这就是打印出来的 因为它们是相同的,这是否意味着等于?还是我遗漏了一点?

  • 本文向大家介绍成本差异和进度差异之间的差异,包括了成本差异和进度差异之间的差异的使用技巧和注意事项,需要的朋友参考一下 对于任何应用程序或专门用于任何项目,最关注的因素之一是在开发前和开发后阶段的预算管理和时间管理。因此,要评估任何项目的这两个主要因素,有很多方法,其中成本差异和进度差异是两个重要且主要的方法。 顾名思义,“成本差异”基于项目开发中花费的成本,而“进度差异”则基于相同开发中花费的时

  • 我使用的是mongoDB PHP,当我使用find查询或聚合框架时,结果是一个游标,我可以使用foreach循环或while循环对游标进行迭代。例如,我要执行以下查询 我可以使用以下两种方法迭代结果