2011-08-23 40 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 (可選的構造函數的第二個參數)。