我知道使用ConcurrentQueue的BlockingCollection的有限容量爲100.BlockingCollection最大尺寸
但是我不確定這是什麼意思。
我試圖實現一個併發緩存,如果隊列大小過大(即緩存溢出時出現鬆散消息),那麼可以在一個操作中進行dequeue,deque/enque操作。有沒有一種方法來使用boundedcapacity,或者是手動執行此操作還是創建新的集合更好?
基本上我有一個閱讀線程和幾個寫線程。如果隊列中的數據是所有編寫者的「最新」,我希望它。
我知道使用ConcurrentQueue的BlockingCollection的有限容量爲100.BlockingCollection最大尺寸
但是我不確定這是什麼意思。
我試圖實現一個併發緩存,如果隊列大小過大(即緩存溢出時出現鬆散消息),那麼可以在一個操作中進行dequeue,deque/enque操作。有沒有一種方法來使用boundedcapacity,或者是手動執行此操作還是創建新的集合更好?
基本上我有一個閱讀線程和幾個寫線程。如果隊列中的數據是所有編寫者的「最新」,我希望它。
N的有界容量意味着如果隊列中已經包含N個項目,則嘗試添加其他項目的任何線程都會阻塞,直到其他線程移除項目爲止。
你似乎想要的是一個不同的概念 - 你希望最近添加的項目成爲消費線程出列的第一個項目。
您可以通過使用ConcurrentStack
而不是底層存儲的ConcurrentQueue來實現。您可以使用this constructor
並通過ConcurrentStack
。
例如:
var blockingCollection = new BlockingCollection<int>(new ConcurrentStack<int>());
使用ConcurrentStack
,可以確保每個項目的消費線程將出列在當時的隊列最新鮮的項目。
另請注意,如果您爲阻止集合指定了上限,則可以使用BlockingCollection.TryAdd()
,如果該集合在您調用它時已滿,將返回false
。
根據我的最新陳述是真實的。但是我仍然希望隊列按照它們入隊的順序進行分派。如果(q.count> x) {q.take(); // donothing} q.add(newitem) 在每次添加之前保留大小,似乎最好做一個 ,但如果另一個線程需要計算長度,然後最終消除不必要的消息 – maxfridbe 2013-04-10 15:17:37
嗯,我不認爲我真的理解你的需求......但是,如果你指定阻塞集合的上限,你可以使用['BlockingCollection。 TryAdd()'](http://msdn.microsoft.com/en-us/library/dd267245.aspx),如果隊列已滿,它將返回false - 你能使用它嗎? – 2013-04-10 15:26:42
這聽起來像你正在嘗試構建像MRU(最近使用)緩存的東西。 BlockingCollection
不是最好的方式來做到這一點。我會建議你改用LinkedList。它不是線程安全的,所以你必須提供自己的同步,但這並不難。您的排隊方法是這樣的:
LinkedList<MyType> TheQueue = new LinkedList<MyType>();
object listLock = new object();
void Enqueue(MyType item)
{
lock (listLock)
{
TheQueue.AddFirst(item);
while (TheQueue.Count > MaxQueueSize)
{
// Queue overflow. Reduce to max size.
TheQueue.RemoveLast();
}
}
}
和出隊就更簡單了:
MyType Dequeue()
{
lock (listLock)
{
return (TheQueue.Count > 0) ? TheQueue.RemoveLast() : null;
}
}
,如果你想消費者做隊列非忙等待這是一個涉及多一點。你可以使用Monitor.Wait
和Monitor.Pulse
。有關示例,請參閱Monitor.Pulse頁面上的示例。
更新:
它發生,我認爲你可以做同樣的事情用一個循環緩衝器(陣列)。只需保持頭部和尾部指針。你插入head
並刪除tail
。如果你去插入,並head == tail
,那麼你需要增加tail
,這有效地刪除了以前的tail
項目。
可能您需要提供有關最新數據的回饋事件嗎? – 2013-04-10 14:31:09