2

我来自 Objective-C 背景,我会使用 Grand Central Dispatch 或 NSOperations 相当简单地解决这个问题。不幸的是,当我尝试在 C# 中构造这个问题时,我认为我陷入了这种思维方式。

我有高级任务,每个任务都有多个可以并行发生的部分。这些部分中的每一个都需要经过管道中的几个阶段。我需要构建这个管道,但知道高级任务何时完成,并执行回调。

使用 GCD,我会创建队列来执行各个部分,每个都链接到流程的下一部分。所有这些部分都将根据它们所属的高级任务进行分组,以便最终触发回调。

我正在努力弄清楚这将如何在 C# 中工作。我一直在研究任务并行库,但对我使用的东西没有特别的偏好。到目前为止,我遇到的一个问题是,如果您完成处理,完成回调似乎只能使用 TPL 管道,但因为我将有多个不会发生的任务。

在概述级别上,如何最好地构造这个问题?我想知道用 Rx 提供并发编写系统是否会更好?

4

3 回答 3

1

在我看来,TPL Dataflow 是正确的方法。Rx 可以做 Dataflow 可以做的任何事情,但在事件/时间管理方面确实表现出色,而 Dataflow 的语法对于实际数据流(包括管道)更清晰。

您是正确的,Dataflow 没有内置任何类型的每项完成通知。您必须自己添加它,例如,通过ActionBlock在每个项目的末尾添加一个。

你可能会发现我的AsyncEx 库很有用。特别是,我有许多异步协调原语,包括AsyncCountdownEvent听起来可能是您需要的。

于 2013-07-28T11:53:59.803 回答
1

我不太明白你的意思是完成回调不是一个选项,因为有多个任务。为每个任务构建一个数据流网络将意味着为它们单独触发完成。

我猜你想避免每次重建网络所产生的开销?在这种情况下,也许你可以在最后添加一个传递块:它返回它给出的任何输入,并调用你需要的任何回调。因此,对于网络产生的每个输出,都会调用回调。如果您想更进一步,它可以改为将消息发布到另一个块,然后可以并行调用回调。

或者,如果管道足够简单,并且您不需要额外的缓冲等等,也许您可​​以使用普通的 TPL 任务来完成它?像这样的东西:

public async Task<string> HighLevelTask(string input1, string input2, Action completed) {
    Task<string[]> parts = Task.WhenAll(Part1(input1), Part2(input2));
    string[] results = await parts;
    completed();
    return string.Join(",", results);
}
public async Task<string> Part1(string input) {
    var result1 = await Stage1(input);
    var result2 = await Stage2(result1);
    return result2;
}
于 2013-07-28T08:30:41.440 回答
0

TPL 足以解决您的情况。我建议您阅读 MSDN 上关于 TPL 中的管道的这篇文章。

于 2013-07-30T08:03:59.043 回答