【发布时间】:2014-01-16 18:27:40
【问题描述】:
我想在以一定的并行度并行处理项目的同时对数据流执行查询。通常,我会为此使用 PLINQ,但我的工作项不受 CPU 限制,而是 IO 限制。我想使用异步 IO。 PLINQ 不支持异步工作。
运行 PLINQ 样式查询但使用异步工作项的最聪明的方法是什么?
这里有一个更详细的问题说明:
我的目标是以以下查询在逻辑上描述的方式处理可能无限的“项目”流:
var items = new int[10]; //simulate data
var results =
from x in items.AsParallel().WithDegreeOfParallelism(100)
where Predicate(x)
select ComputeSomeValue(x);
foreach (var result in results)
PerformSomeAction(result);
这个查询只是真实查询的草图。现在我希望每个占位符函数都是异步(返回一个Task 并且在内部基于异步IO)。
请注意,内存中存储的项目可能远远多于可存储的项目。我还必须控制并行度,以最大限度地利用底层网络和磁盘硬件。
这个问题与多核无关。它完全适用于只有一个 CPU 内核的机器,因为 IO 仍然可以从并行性中受益。想想缓慢的网络服务调用等。
【问题讨论】:
-
+1,好问题。我想知道您是否可以利用 IO 端的完成端口来实现并行性?免责声明:我在 C++ 中经常使用它们,但从未在 C# 中使用它们。
-
您说过“工作项不受 CPU 限制,而是 IO 限制”。因此,大量内核和 CPU 并行性不会有太大帮助。我的意思是,如果这两个操作的 CPU 使用率低且 I/O 使用率高,则创建 n = 10 个链式操作(ComputeSomeValue,由 PerformSomeAction 继续)并按顺序启动链。 新任务(ComputeSomeValue).ContinueWith(...) 等
-
您可以使用 PLINQ(CPU 并行性)应用您拥有的过滤器,但仅此而已...您必须为 I/O 部分启动任务...恕我直言。
-
您看过 TPL 数据流吗?显然比原始 PLINQ 更冗长,但似乎完全符合您的需要。如果你很棒,为它创建一组 LINQ 绑定,以便它可以用 LINQ 语法表达。
-
@Noseratio 是的。我希望这个问题能够提供一些一般性的见解,并适用于具有类似“管道”结构的所有问题。
标签: .net asynchronous task-parallel-library plinq