C# 在单机上实现低延迟、高吞吐量数据传输的最佳并发框架

C# 在单机上实现低延迟、高吞吐量数据传输的最佳并发框架,c#,multithreading,asynchronous,concurrency,task-parallel-library,C#,Multithreading,Asynchronous,Concurrency,Task Parallel Library,我正在寻找如何使用C#为我的特定体系结构实现并发框架的想法: 我实现了几个模块/容器(实现为类),它们都单独连接到消息总线。每个模块要么主要生产,要么主要消费,但所有模块还实现了一个请求/应答模式,用于两个给定模块之间的通信。我对并发和异步编程非常陌生,但本质上希望以并发方式而不是同步方式运行整个体系结构。我将非常感谢一些技术(TPL,THealPoCurt,CTP,开源库,…)为我的特定用例考虑的指针,给出以下要求: 整个系统仅在本地机器上运行(进程中,甚至消息总线) 至少有一个模块执行大量

我正在寻找如何使用C#为我的特定体系结构实现并发框架的想法:

我实现了几个模块/容器(实现为类),它们都单独连接到消息总线。每个模块要么主要生产,要么主要消费,但所有模块还实现了一个请求/应答模式,用于两个给定模块之间的通信。我对并发和异步编程非常陌生,但本质上希望以并发方式而不是同步方式运行整个体系结构。我将非常感谢一些技术(TPL,THealPoCurt,CTP,开源库,…)为我的特定用例考虑的指针,给出以下要求:

  • 整个系统仅在本地机器上运行(进程中,甚至消息总线)
  • 至少有一个模块执行大量IO(每秒从物理驱动器读取数百万条16字节的消息),在整个过程中将多个16字节的数据块发布到阻塞集合
  • 另一个模块在整个时间内消耗来自阻塞集合的数据
  • 入口点是生产者开始发布消息,出口是生产者完成发布一组有限的16字节消息
  • 由于吞吐量和延迟的原因,唯一绕过消息总线的通信是向阻塞集合发布/消费消息。(我很高兴听到关于删除消息总线的建议,如果它是合理的)
  • 其他模块处理诸如写入SQL数据库、发布到GUI服务器、连接到与外部服务器通信的API等操作。此类操作运行频率较低/受到限制,并且可能作为任务运行,而不是在整个系统运行过程中使用整个线程
  • 我在64位、四核、16gb内存机器上运行,但理想情况下,我希望实现一个也可以在双核机器上运行的解决方案
考虑到我希望管理的内容,您建议我应该关注哪些并发实现

EDIT:我想强调的是,我面临的最大问题是如何方便地将每个容器/模块连接到线程/任务池,以便每个模块都异步运行,同时仍然提供这些模块之间的完全进出通信。在我没有解决将所有模块连接到能够动态处理所涉及的任务/线程数量的并发平台之前,我并不太关心优化单个生产者/消费者模式

我推荐这样的任务,在这样的任务中,您具有高吞吐量、低延迟和定义良好的数据流

如果您愿意牺牲一些性能来进行线程管理,那么它可能适合您。它在使用TPL进行任务调度方面做得很好。

如果您正在寻找一种基于框架的并发解决方案,您也可以进行研究。我认为这可能适合您的设计理念。
否则,我将遵循这样的规则,即在应用程序的整个生命周期内运行某些内容时,应使用线程,而对于短时间运行的项目,则应使用任务。
我认为更重要的是,明确定义一致性的责任,以便您以后可以更改框架
与通常编写快速代码一样,没有经验法则,但需要大量使用小存根进行测试,以测量实际性能。

我发现了n-act,这是一个用于.Net的Actors框架,它几乎实现了我正在寻找的功能。在我的问题中,我描述了我寻找更大的框架建议,在我看来,Actor框架解决了我需要的问题。我并不是说我将实现n-act库,但它是一个设置参与者的好例子,参与者可以异步通信,并且可以在自己的线程上运行。消息传递还支持新的C#5异步/等待功能

上面提到了Disruptor,还有TPL和其他一些想法,我很欣赏这些想法,它确实让我思考,我花了相当多的时间来理解每个库/框架试图针对什么以及它试图解决什么问题,因此这些想法非常有成效

然而,对于我的特殊情况,我认为Actors框架正是我所需要的,因为我主要关心的是异步数据流的交换。不幸的是,我还没有看到在任何.Net技术中实现多少Actor模型。TPL数据流看起来非常有前景,但正如魏斯马特指出的,它还没有做好生产准备

如果N-Act不能被证明是稳定的或可用的,那么我将通过TPL寻找一个定制的实现。无论如何,现在是时候充分理解TPL必须提供的一切,并在设计阶段开始并行思考,而不是试图将同步模型转换为异步框架


总之,“演员模型”是我想要的

当您从光盘中读取数据时,如果您从您的要求中读取字符串数据(请参阅),您的速度将不会超过20MB/s。您希望使用.NET读取16MB/s-48MB/s的数据。这是可以实现的,但一个过程所能达到的极限是有限的。在这种情况下,您主要受到GC的限制。我会切换到C++或托管C++以获得期望的读取性能,而不需要太多的GC开销,返回到.NET.您的体系结构还不清楚。您的消息总线是如何实现的?”16字节消息”-存在一个问题。无论您如何实现系统,此消息对于高效的线程间通信来说都太小。你能把它们拼凑起来,让4K块的信息排队吗?@Alois,我强烈不同意你的观点。首先,我指出我读取字节数组(16字节消息),而不是字符串数据。其次,我目前处理每秒2400万条16字节的未解析消息的读取吞吐量,以及