2012-06-01 36 views
7

我有一個遞歸問題,其中消費者在樹的每個級別上執行一些工作,然後需要遞歸樹並在下一級執行相同的工作。當生產者也是消費者時,如何在生產者/消費者模式中使用阻止收集 - 如何結束?

我想使用ConcurrentBag/BlockingCollection等並行運行。在這種情況下,隊列的使用者也是隊列的生產者!

我的問題是這樣的:使用BlockingCollection,我可以寫很簡單的foreach邏輯出隊的項目,排隊新的 - 當隊列爲空,阻塞集合將正確地阻止,並等待新的工作由生產其他消費者之一。

但我怎麼知道所有的消費者是否阻止?!

我知道CompleteAdding(),但似乎沒有服務,因爲唯一一次實際完成的是當所有生產者完成生產並且隊列爲空時 - 並且由於它們都將被阻塞,有沒有人「免費」設置CompleteAdding()。有沒有辦法檢測到這個? (也許一個事件,可以在阻塞時觸發,並在解除阻塞時再次觸發?)

我可以通過不使用foreach手動處理,但是手動有一段時間(!完成)循環,並使用TryTake,但那麼我需要手動睡眠,這似乎是無效的(整個原因有阻塞集合,只有併發集合在第一位!)每次通過循環,如果TryTake是假的,我可以設置一個空閒標誌,然後有一個主檢查,如果隊列是空的,並且所有的線程都是空閒的,設置一個完整的標誌,但是再次,這看起來很糟糕。

直覺告訴我有一些方法來使用Blocking Collection來做到這一點,但我不能完全達到目的。

無論如何,人有當消費者是生產者和能夠檢測何時釋放所有塊將是真棒

+1

好問題。任何帶有外部標誌或事件的事情似乎都適合比賽條件。 –

+0

處理器(組合消費者/生產者)是否有很多狀態或需要大量資源?你可以重新解決這個問題嗎?創建一個Task,每個只執行一次迭代? –

+0

@Damien_The_Unbeliever:是的,我可以做單一的迭代,事實上已經有了這個工作,但我試圖使用生產者/消費者模式,因爲這是可能在未來被遷移到雲的代碼,其中工作者角色將是以相同的方式使用Azure隊列存儲,並且我想保持兩個實現之間的整體邏輯儘可能相似。在這種情況下,我將被迫檢查工人是否全部閒置以確定排隊是否完成,但似乎我應該儘可能高效地在本地 - 也只是想弄清楚:) –

回答

-3

我覺得從MSDN這個鏈接可以幫助你的良好格局。

Reusable Parallel Data Structures and Algorithms

它暴露了如何處理併發情況下的一些數據結構。

+1

從2007年的數據結構並沒有解決我關於4.0併發庫的問題 –

+0

所以使用4.0自己實現它們,它只是一個指南,而不是「答案」。 – oarrivi