如何使用BlockingCollection拥有许多消费者线程

时间:2013-07-31 19:07:08

标签: c#-4.0 producer-consumer

我正在使用支持BlockingCollection的生产者/消费者模式从文件中读取数据,解析/转换然后插入到数据库中。我的代码与此处的代码非常相似:http://dhruba.name/2012/10/09/concurrent-producer-consumer-pattern-using-csharp-4-0-blockingcollection-tasks/

然而,主要区别在于我的消费者线程不仅解析数据而且还插入数据库。这个位很慢,我认为是导致线程阻塞。

在该示例中,有两个消费者线程。我想知道是否有办法让线程数以某种智能方式增加?我原以为线程池会这样做,但似乎无法理解如何做到这一点。

或者,您将如何选择消费者线程的数量? 2对我来说似乎不正确,但我不确定最好的#会是什么。关于选择消费者线程数的最佳方法的想法?

1 个答案:

答案 0 :(得分:3)

选择消费者线程数量的最佳方法是数学:计算每分钟从生产者进入的数据包数量,除以单个消费者每分钟可以处理的数据包数量,并且你有一个非常好的了解您需要多少消费者。

我通过添加消费者将其已完成的数据包放入的另一个BlockingCollection解决了阻塞输出问题(消费者在尝试更新数据库时阻塞)。一个单独的线程读取该队列并更新数据库。所以它看起来像:

input thread(s) => input queue => consumer(s) => output queue => output thread

这具有将消费者与输出分开的额外好处,这意味着您可以优化输出或完全更改输出方法而不会影响消费者。例如,这可能允许您批量处理数据库更新,这样您就可以通过一次调用更新十几个或一百个(或更多)记录,而不是每个记录进行一次数据库调用。

我在文章Simple Multithreading, Part 2中展示了一个非常简单的例子(使用单个消费者)。这适用于文本文件过滤器,但概念是相同的。