我阅读过很多技术文档,包括一些由Microsoft团队或其他作者编写的有关新TPL Dataflow库、async/await并发框架和TPL功能的详细说明。然而,我并没有真正找到清晰地区分它们各自应该在何时使用的内容。我知道每个工具都有其适用性和应用场景,但具体来说:
我有一个完全在进程内运行的数据流模型。在顶部是一个数据生成组件(A),它生成数据并通过数据流块链接或通过触发事件传递给处理组件(B)。其中的一些部分必须同步运行,而(A)大量受益于并行性,因为大多数过程都是I/O或CPU绑定的(从磁盘读取二进制数据,然后对其进行反序列化和排序)。最终,处理组件(B)将转换后的结果传递给(C)以供进一步使用。
具体来说,我想知道何时使用任务(tasks)、async/await和TPL数据流块以解决以下问题:
启动数据生成组件(A)。我显然不想锁定gui/dashboard界面,因此这个过程必须在不同的线程/任务上运行。
如何调用(A)、(B)和(C)中未直接涉及数据生成和处理过程的方法,但执行配置工作可能需要几百毫秒/秒来返回。我的直觉是这正是async/await发挥作用的地方?
我最困扰的是如何最好地设计组件之间的消息传递。TPL Dataflow看起来非常有趣,但有时对我的目的来说太慢了。如果不使用TPL Dataflow,如何通过进程内的任务并发传递数据以实现响应性和并发性?例如,显然,如果在任务中引发事件,则订阅的事件处理程序将在同一任务中运行,而不是传递到另一个任务中。简而言之,在将数据传递给组件(B)后,组件(A)如何继续其业务,同时组件(B)检索数据并专注于处理它?哪种并发模型在这里最好使用?
我想总结上述问题,我的困境就是如何使用标准实践设计和实现API类型组件?方法是否应该设计为异步,数据输入作为数据流块,数据输出作为数据流块或事件?通常哪种方法是最好的?我问这个问题是因为上面提到的大多数组件都应该独立工作,所以它们可以基本上被交换或内部独立地修改而不必重写访问器和输出。
关于性能的注意事项:我提到TPL Dataflow块有时很慢。我处理高吞吐量、低延迟类型的应用程序,目标是磁盘I/O极限,因此TPL Dataflow块的性能通常比例如同步处理单元要慢得多。问题在于我不知道如何将进程嵌入到自己的任务或并发模型中,以实现与TPL Dataflow块已经处理的类似功能,但没有TPL df带来的开销。