我一直使用這個代碼作爲隊列,在Dequeue()
上阻塞,直到一個元素入隊。我已經在幾個項目中使用了這些代碼幾年了,所有這些都沒有問題......直到現在。我正在看到我正在寫的一些代碼陷入僵局,並且在調查這個問題時,我的'懷疑的眼睛'已經解決了這個問題BlockingQueue<T>
。我無法證明這一點,所以我想我會問一些比我更聰明的人來回顧一下潛在的問題。你們可以看到任何可能導致此代碼出現死鎖的東西嗎?這個BlockingQueue是否容易死鎖?
public class BlockingQueue<T>
{
private readonly Queue<T> _queue;
private readonly ManualResetEvent _event;
/// <summary>
/// Constructor
/// </summary>
public BlockingQueue()
{
_queue = new Queue<T>();
_event = new ManualResetEvent(false);
}
/// <summary>
/// Read-only property to get the size of the queue
/// </summary>
public int Size
{
get
{
int count;
lock (_queue)
{
count = _queue.Count;
}
return count;
}
}
/// <summary>
/// Enqueues element on the queue
/// </summary>
/// <param name="element">Element to enqueue</param>
public void Enqueue(T element)
{
lock (_queue)
{
_queue.Enqueue(element);
_event.Set();
}
}
/// <summary>
/// Dequeues an element from the queue
/// </summary>
/// <returns>Dequeued element</returns>
public T Dequeue()
{
T element;
while (true)
{
if (Size == 0)
{
_event.Reset();
_event.WaitOne();
}
lock (_queue)
{
if (_queue.Count == 0) continue;
element = _queue.Dequeue();
break;
}
}
return element;
}
/// <summary>
/// Clears the queue
/// </summary>
public void Clear()
{
lock (_queue)
{
_queue.Clear();
}
}
}
另一方面,.NET 4現在支持內置的'System.Collections.Concurrent.ConcurrentQueue'。 –
2010-05-07 14:36:13
@丹·布萊恩特:那不是阻塞隊列。 – 2010-05-07 22:42:43
您可以將其封裝在新的BlockingCollection中,該Blocking可以訪問任何潛在的「IProducerConsumerCollection 」。見http://msdn.microsoft.com/en-us/library/dd997371%28v=VS.100%29.aspx –
2010-05-07 23:50:09