图像说的不仅仅是文字,所以这基本上是我想要达到的目的:
(为了简洁起见,我也使用了水果类比)
我过去很多次使用.Net类的不同之王(BackGroundWOrkers,ThreadPool,Self Made Stuff ......)完成了这种事情。
我在这里要求提供建议,并就如何有效地做到这一点获得新的想法
这是一个高计算程序,因此我收到数百万(结构相似但内容不相似)的数据,这些数据必须排队才能根据其内容类型进行处理。因此,我想避免为每个要处理的单个数据创建并行任务(这会使CPU过载并且设计不佳恕我直言)。这就是为什么我想到只有一个线程运行EACH数据TYPE,专门处理它(知道“Press Juice”方法是通用的,独立于要按下的水果)
欢迎任何想法和实施建议。
我可以自由地提供任何进一步的细节。
答案 0 :(得分:19)
TPL DataFlow似乎是一个非常强大的候选人。
答案 1 :(得分:9)
如果您真正想要的是每种类型的水果的一个线程(或一个恒定数量的线程),那么最简单的解决方案可能是对每种类型的水果使用BlockingCollection
。您的数据总线将为这些集合提供水果,您的处理线程将从中获取。但这意味着如果现在没有苹果,线程将被阻止,什么都不做。
更灵活,更有效的方法是使用TPL Dataflow。有了这个,你不使用线程或任务,你使用块。例如,您的Thread C可以表示为TransformBlock<Apple, AppleJuice>
。
默认情况下,每个块最多使用一个线程,但可以轻松配置它们以使用更多线程(通过设置MaxDegreeOfParallelism
)。此外,数据流块可以很好地适应新的C#5.0 async
- await
,这可能是一个很大的优势。
还有一些你应该小心的事情。例如,默认情况下,TDF针对吞吐量而非延迟进行了优化。因此,如果你的线程池很忙并且你有很多橙子进来而且只有一个苹果,那么苹果可能只在所有橙子被处理后才会被处理掉。但这也可以通过正确配置块来解决(通过设置MaxMessagesPerTask
)。
答案 2 :(得分:1)
我会警告“每种数据类型的工作线程”方法。这假设实际输入负载将符合开发人员方便的等价类。你知道香蕉比橘子慢5倍吗?如果每个星期二都是“苹果庆祝日”,每个人都会吃比平时多的水果,那么会发生什么呢?所有这些都是苹果?
并行运行是关于性能,而不是关于域。不要在域之后对其进行建模,对其进行建模以提供最低的平均周期时间。