【问题标题】:Task vs Barrier任务与障碍
【发布时间】:2015-07-28 18:44:04
【问题描述】:

所以我的问题如下:我有一个要处理的项目列表,我想并行处理这些项目,然后提交已处理的项目。

C# 中的屏障类将允许我执行此操作 - 我可以并行运行线程来处理项目列表,当调用 SignalAndWait 并且所有参与者都遇到障碍时,我可以提交已处理的项目。

Task 类也允许我执行此操作 - 在 Task.WaitAll 调用中,我可以等待所有任务完成,然后我可以提交已处理的项目。如果我理解正确,每个任务都将在它自己的线程上运行,而不是在同一个线程上并行运行一堆任务。

  1. 我对问题的两种用法的理解是否正确?
  2. 两者之间有什么优势吗?
  3. 混合解决方案有什么更好的方法(障碍和任务?)。

【问题讨论】:

  • 从来不知道Barrier。阅读后,也许 TPL Dataflow 更符合您的喜好?
  • 在处理数据时,您是在做 IO 密集型工作还是 CPU 密集型工作?

标签: c# task barrier


【解决方案1】:

我对问题的两种用法的理解是否正确?

我认为您对Barrier 类有误解。 The docs say:

屏障是用户定义的同步原语,它允许多个线程(称为参与者)分阶段并发地处理算法。

屏障是一种同步原语。将其与可以并行计算的工作单元(例如 Task)进行比较是不正确的。

屏障可以向所有线程发出信号,等待所有其他线程完成某些工作并检查该工作。它本身没有并行计算能力,也没有背后的线程模型。

两者之间有什么优势吗?

至于问题 1,你看这无关紧要。

混合解决方案有什么更好的方法(障碍和任务?)。

在你的情况下,我不确定它是否需要。如果您只想在一组项目上并行执行 CPU 绑定计算,那么 Parallel.ForEach 正是为此目的。它将对一个可枚举对象进行分区并并行调用它们,然后阻塞直到整个集合被计算完毕。

【讨论】:

  • 很好的答案我理解其中的区别,现在如果我告诉你我正在使用 EF 来提取信息并运行计算,然后一旦处理 - 我将提交处理过的记录。在您的示例中,我将使用 Parallel.foreach 处理要处理的项目并运行计算?
  • @Pr0ph3t 是的。我将从 EF 查询数据(同步或异步,无论您选择哪个),一旦数据加载到内存中,我将使用 Parallel.ForEach 运行这些计算。您也可以查看PLINQ,这可能符合您的需求。
  • 看起来 Parallel.ForEach 和 EF 可能还有其他问题 - 但这是另一个话题。
  • @Pr0ph3t 您不应该在操作的查询部分使用Parallel.ForEach!查询数据后使用。如果您需要同时访问数据库,请查看 EF 公开的异步 API。
【解决方案2】:

我没有直接回答你的问题,因为我认为处理障碍和任务只会让你的代码比它需要的更复杂。

我建议为此使用 Microsoft 的反应式框架 - NuGet "Rx-Main" - 因为它让整个问题变得超级简单。

代码如下:

var query =
    from item in items.ToObservable()
    from processed in Observable.Start(() => processItem(item))
    select new { item, processed };

query
    .ToArray()
    .Subscribe(processedItems =>
    {
        /* commit the processed items */
    });

查询将项目列表转换为可观察对象,然后使用Observable.Start(...) 处理每个项目。这会根据需要以最佳方式启动新线程。 .ToArray() 采用单个结果的序列并将其更改为单个结果数组。然后.Subscribe(...) 方法允许您处理结果。

代码比使用任务或障碍要简单得多。

【讨论】:

  • 但是他真的需要流式传输中的数据吗?不确定。另外,我看不出处理任务或Parallel.ForEach 比 Rx 复杂吗?
  • @YuvalItzchakov - 你所说的“流媒体”是什么意思?
  • Rx 将在查询完成时将输出流式传输到Subscribe
  • @YuvalItzchakov - .ToArray() 将收集所有值并立即将它们全部传递出去。这就是 OP 想要的。
猜你喜欢
  • 2017-03-01
  • 2021-07-15
  • 2017-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多