2011-08-23 61 views
8

我正在开发一个Windows窗体应用程序(c#),并且在程序运行时,它创建的对象将它们添加到列表中。我必须用FIFO(先进先出)处理列表中的项目。我想在backgroundthread中做到这一点,我必须按顺序处理它们,编号1,编号2,编号3等等。只要一个项目被添加到列表中,我想处理它。所以我必须有一些东西来检查这个列表。BlockingCollection或队列<T>找工作?

达到此目的的最佳方法是什么?

我知道blockingcollection做了类似的事情,它在处理它之前等待要添加的项目。

我可以在队列中使用单个线程,并且只需要(true)并在有物品时使用物品?

您认为如何?

回答

14

如果您打算使用后台线程,则您应该使用BlockingCollection<T>。你可以很容易地做同样的while(true)逻辑,你正在寻找。

BlockingCollection<T>给你你两个重要特征

  1. 这是线程安全的

  2. 当你调用Take(),它会阻止(即等到事情是在队列中),所以你不需要用ManualResetEvents等编写任何代码,这是一个很好的简化。

+0

是的!我只是要求这个确认我的想法,如果有人有一个更好的主意:) – syncis

+2

@Jonathan Beerhalter:或者,而不是调用'Take',他可以让他的后台线程在['GetConsumingEnumerable']上执行'foreach' (http://msdn.microsoft.com/en-us/library/dd287186.aspx),它将放置在“BlockingCollection ”中的项目。 – casperOne

+0

@syncis:'GetConsumingEnumerable'将会阻塞,直到一个项目被添加到'BlockingCollection ''就像'Take'将;事情是,除了处理这些项目,你的后台线程还有什么其他功能?如果您尝试保存线程;不,你基本上是重写线程池,这通常不是一个好主意。请注意,在您逐一处理您的项目时(或者您可以根据您的需要,将这些项目发送给其他线程处理),可以通过'GetConsumingEnumerable'获取更多项目。 – casperOne

0

,如果你想阻止如果队列为空,然后用BlockingCollection - 这是理想的... 如果你想更类似队列(自己决定如何处理一个空的),然后ConcurrentQueue

无论是线程安全的,在ConcurrentQueue大多数操作实现无锁这样的真快......无论哪种方式直接使用或作为例如BlockingCollection<string> = new BlockingCollection<string> (new ConcurrentQueue<string>)基本类型为您BlockingCollection - 你甚至可以把上最大capactiy (可选的构造函数的第二个参数)。