0

消費者線程和多個生產者線程將其工作與System.Collections.Concurrent.BlockingCollection<T>同步。在不消費的情況下觀察BlockingCollection中的更改

製片方稱blockingCollection.Add()
和消費運行
foreach (var item in blockingCollection.GetConsumingEnumerable()) {...}

現在,一個製片人想「刷新」緩衝區:生產者要等到所有當前項目已被消耗。其他生產者可能會在此期間添加更多項目,但該生產者只對當前隊列中的項目感興趣。

我該如何讓製片人等待,不用忙碌的等待呢?

實質上我希望有一些非消費者線程在BlockingCollection的某個項目被消費時得到通知

我可以設置在消費的的AutoResetEvent,但這會醒來只有一個線程等待的變化,當時可能有多個:

foreach (var item in blockingCollection.GetConsumingEnumerable()) 
{ 
    myAutoResetEvent.Set() 
} 

我還可以設置一個ManualResetEvent的:

foreach (var item in blockingCollection.GetConsumingEnumerable()) 
{ 
    myManualResetEvent.Set() 
} 

這會喚醒所有等待的線程,但是如何將它切換回來?

+0

爲什麼你需要喚醒消費者在所有集合中的情況?如果他們使用'GetConsumingEnumerable',他們已經在等待序列中的新項目,並且只要有新項目可用就會開始處理新項目。 – Servy

+0

我想要通知非消費者線程。消費者當然會自動獲取他們的更新。但是現在我想通知一些其他不消耗項目的線程。 – HugoRune

+0

在集合中放置一個虛擬物品,喚醒生產者。 – Paparazzi

回答

3

在你最終使用我的評論

把虛擬物品,其喚醒生產者

+0

是的,這對我有用。我現在爲我的緩衝項目創建一個包裝類,它可以包含一個額外的ManualResetEventSlim。每當生產者想要得到通知時,它就會插入一個虛擬物品,這個物品將由消費者提出。 – HugoRune

相關問題