是否有相當於Monitor.Pulse
和Monitor.Wait
,我可以結合使用ReaderWriterLockSlim
?ReaderWriterLockSlim和脈衝/等待
我有一個類,我已經封裝了對底層隊列的多線程訪問。爲了排隊,我獲得了一個保護底層隊列的鎖(以及一些其他對象),然後添加該項並鎖定對象以表示某些內容已添加到隊列中。
public void Enqueue(ITask task)
{
lock (mutex)
{
underlying.Enqueue(task);
Monitor.Pulse(mutex);
}
}
在隊列的另一端,我有一個後臺線程,當它們到達隊列時不斷處理消息。當隊列中沒有項目時使用Monitor.Wait
,以避免不必要的輪詢。 (我認爲這是很好的設計,但(在合理範圍內)任何火焰的歡迎,如果他們幫助我,否則學習。)
private void DequeueForProcessing(object state)
{
while (true)
{
ITask task;
lock (mutex)
{
while (underlying.Count == 0)
{
Monitor.Wait(mutex);
}
task = underlying.Dequeue();
}
Process(task);
}
}
隨着越來越多的業務都加入到這一類(需要只讀訪問鎖受保護的基礎),有人建議使用ReaderWriterLockSlim
。我以前從未使用過這個課程,並且假設它可以提供一些性能優勢,但我並不反對它,但前提是我可以保留Pulse/Wait設計。
對於反饋...我不會認爲從'Wait'喚醒意味着「有數據」;我會打'繼續;'並再次檢查。這種方法使得稍後添加停止/排放設施更容易。如果您添加到以前爲空的隊列,您也可能只想要「脈衝」;否則,什麼都沒有在等待。 – 2010-04-22 15:55:35
我喜歡在將單個項目添加到隊列後執行脈衝的想法。然而,我還有一些關於我的代碼的疑問(以及我應該,它是多線程的)以及計數隊列中項目的效率並將該值與0進行比較(我希望它不會走路一個鏈接列表來做計數)。我想我應該真的調用PulseAll以防萬一它是另一個接收單脈衝的寫線程。 – Jono 2010-04-22 21:14:01
我同意'PulseAll'。請參閱「計數」,請參閱文檔:http://msdn.microsoft.com/en-us/library/fy0wwyz4.aspx「檢索此屬性的值是O(1)操作。」;含義:不,它不這樣做 - 它分開知道「Count」。 – 2010-04-22 21:32:27