19

图像胜于雄辩,所以这基本上是我想要实现的目标:(
为了通用性和简单性,我还使用了水果类比)
在此处输入图像描述

过去我曾多次使用不同的 .Net 类之王(BackGroundWOrkers、ThreadPool、Self Made Stuff...)做过这种事情

我在这里询问是为了获得建议并获得有关如何有效地做到这一点的新想法。
这是一个高计算程序,所以我收到数百万(结构相似但内容不同)数据,这些数据必须排队才能根据其内容类型进行处理。因此,我想避免为每个要处理的单个数据创建一个并行任务(这会使 CPU 过载并且恕我直言设计不佳)。这就是为什么我想为每种数据类型只运行一个线程,专门用于处理它(知道“榨汁”方法是通用的并且独立于要压榨的水果)

欢迎任何想法和实施建议。
我可以自由提供任何进一步的细节。

4

3 回答 3

19

TPL DataFlow似乎是一个非常强大的候选者。

在这里阅读介绍。

于 2013-01-08T10:32:50.627 回答
10

如果您真正想要的只是每种水果都有一个线程(或恒定数量的线程),那么最简单的解决方案可能是BlockingCollection对每种水果使用一个。您的数据总线会将结果传递给这些集合,而您的处理线程将从它们中获取。但这意味着如果现在没有苹果,线程将被阻塞,什么都不做。

一种更灵活、更有效的方法是使用 TPL 数据流。这样,您就不用处理线程或任务,而是处理块。例如,您的线程 C 可以表示为TransformBlock<Apple, AppleJuice>.

默认情况下,每个块最多使用一个线程,但它们可以很容易地配置为使用更多线程(通过设置MaxDegreeOfParallelism)。此外,数据流块可以很好地与新的 C# 5.0 async-配合使用await,这可能是一个很大的优势。

还有一些事情你应该小心。例如,默认情况下,TDF 针对吞吐量而不是延迟进行了优化。因此,如果您的线程池很忙,并且您有很多橙子进入并且只有一个苹果,则可能只有在所有橙子都处理完之后才会处理苹果。但这也可以通过正确配置块(通过设置MaxMessagesPerTask)来解决。

于 2013-01-08T13:48:13.287 回答
1

我会警告不要使用“每种数据类型的工作线程”方法。这假设实际输入负载将符合开发人员方便的等价类。你知道香蕉榨汁的速度是否比橙子慢 5 倍?如果每个星期二都是“苹果庆祝日”,每个人都比平时榨出更多的果汁,而且全是苹果,会发生什么?

并行运行是关于性能的,而不是关于域的。不要在您的领域之后对其进行建模,而是对其进行建模以提供最低的平均周期时间。

于 2013-01-08T14:24:07.490 回答