我會做像下面的類。當您生成一個項目以將其添加到其中一個隊列時,您可以撥打Enqueue()
。這種方法總是立即返回(幾乎)。在另一個線程中,當您準備好使用某個物品時,請致電Dequeue()
。它試圖首先從高優先級隊列中取出。如果在任何隊列中沒有可用項目,則呼叫阻止。當你完成生產時,你可以撥打Complete()
。在該呼叫已經完成並且兩個隊列都是空的情況下,下一個呼叫(或當前被阻止的呼叫)到Dequeue()
將拋出InvalidOperationException
。
如果您的製片人長時間比您的消費者更快,您應該排隊(new BlockingCollection<T>(capacity)
)。但在這種情況下,如果只有一個線程同時產生低優先級和高優先級項目,那麼高優先級項目可能需要等待低優先級項目。你可以通過一個線程來產生高優先級的項目和一個低優先級的項目來解決這個問題。或者你只能綁定高優先級的隊列,並希望你不會一次獲得一百萬個低優先級的項目。
class Worker<T>
{
BlockingCollection<T> m_highPriorityQueue = new BlockingCollection<T>();
BlockingCollection<T> m_lowPriorityQueue = new BlockingCollection<T>();
public void Enqueue(T item, bool highPriority)
{
BlockingCollection<T> queue;
if (highPriority)
queue = m_highPriorityQueue;
else
queue = m_lowPriorityQueue;
queue.Add(item);
}
public T Dequeue()
{
T result;
if (!m_highPriorityQueue.IsCompleted)
{
if (m_highPriorityQueue.TryTake(out result))
return result;
}
if (!m_lowPriorityQueue.IsCompleted)
{
if (m_lowPriorityQueue.TryTake(out result))
return result;
}
if (m_highPriorityQueue.IsCompleted && m_lowPriorityQueue.IsCompleted)
throw new InvalidOperationException("All work is done.");
else
{
try
{
BlockingCollection<T>.TakeFromAny(
new[] { m_highPriorityQueue, m_lowPriorityQueue },
out result);
}
catch (ArgumentException ex)
{
throw new InvalidOperationException("All work is done.", ex);
}
return result;
}
}
public void Complete()
{
m_highPriorityQueue.CompleteAdding();
m_lowPriorityQueue.CompleteAdding();
}
}
非常感謝!我非常欣賞這些信息和建議! – user685869 2011-04-01 14:00:03