我有一個遞歸問題,其中消費者在樹的每個級別上執行一些工作,然後需要遞歸樹並在下一級執行相同的工作。當生產者也是消費者時,如何在生產者/消費者模式中使用阻止收集 - 如何結束?
我想使用ConcurrentBag/BlockingCollection等並行運行。在這種情況下,隊列的使用者也是隊列的生產者!
我的問題是這樣的:使用BlockingCollection,我可以寫很簡單的foreach邏輯出隊的項目,排隊新的 - 當隊列爲空,阻塞集合將正確地阻止,並等待新的工作由生產其他消費者之一。
但我怎麼知道所有的消費者是否阻止?!
我知道CompleteAdding(),但似乎沒有服務,因爲唯一一次實際完成的是當所有生產者完成生產並且隊列爲空時 - 並且由於它們都將被阻塞,有沒有人「免費」設置CompleteAdding()。有沒有辦法檢測到這個? (也許一個事件,可以在阻塞時觸發,並在解除阻塞時再次觸發?)
我可以通過不使用foreach手動處理,但是手動有一段時間(!完成)循環,並使用TryTake,但那麼我需要手動睡眠,這似乎是無效的(整個原因有阻塞集合,只有併發集合在第一位!)每次通過循環,如果TryTake是假的,我可以設置一個空閒標誌,然後有一個主檢查,如果隊列是空的,並且所有的線程都是空閒的,設置一個完整的標誌,但是再次,這看起來很糟糕。
直覺告訴我有一些方法來使用Blocking Collection來做到這一點,但我不能完全達到目的。
無論如何,人有當消費者是生產者和能夠檢測何時釋放所有塊將是真棒
好問題。任何帶有外部標誌或事件的事情似乎都適合比賽條件。 –
處理器(組合消費者/生產者)是否有很多狀態或需要大量資源?你可以重新解決這個問題嗎?創建一個Task,每個只執行一次迭代? –
@Damien_The_Unbeliever:是的,我可以做單一的迭代,事實上已經有了這個工作,但我試圖使用生產者/消費者模式,因爲這是可能在未來被遷移到雲的代碼,其中工作者角色將是以相同的方式使用Azure隊列存儲,並且我想保持兩個實現之間的整體邏輯儘可能相似。在這種情況下,我將被迫檢查工人是否全部閒置以確定排隊是否完成,但似乎我應該儘可能高效地在本地 - 也只是想弄清楚:) –