public void EnqueueTask(int[] task)
{
lock (_locker)
{
_taskQ.Enqueue(task);
Monitor.PulseAll(_locker);
}
}
所以,在這裏,我將元素添加到我的隊列中,而不是線程對它們進行一些處理。如何將項目異步添加到隊列中?如何在C#中將隊列添加到隊列<T>?
public void EnqueueTask(int[] task)
{
lock (_locker)
{
_taskQ.Enqueue(task);
Monitor.PulseAll(_locker);
}
}
所以,在這裏,我將元素添加到我的隊列中,而不是線程對它們進行一些處理。如何將項目異步添加到隊列中?如何在C#中將隊列添加到隊列<T>?
如果你使用.net V4看看新的線程安全集合,他們大多沒有阻塞,所以將適當地避免需要一個異步添加。
ConcurrentQueue
順便說一句,謝謝:)。我有來自.NET 4的新線程安全集合的書籤,並且您幫助我記住它們) – 2010-10-27 09:07:55
也許這樣的事情可以工作:
void AddToQueue(Queue queue, string mess) {
var t = new Thread(() => Queue.Synchronized(queue).Enqueue(mess));
t.Start();
}
新線程確保您的當前線程不會阻止。
Queue.Syncronized處理隊列的所有鎖定。 它可以替換你的儲物櫃代碼,可能會有更好的表現。
由於您使用隊列<T>(推薦),因此無法使用Queue.Synchronized。
但除此之外,我會使用線程池。但是你的EnqueueTask方法意味着線程邏輯在你的「TaskQueue」類之外處理(你的方法意味着它是一個任務隊列)。
你的實現也意味着它不是「這裏」,我們不是要添加邏輯,而是在另一個地方,你在那裏的代碼並沒有真正阻塞很長時間,所以我會把事情顛倒過來。
這也意味着事情離開隊列的東西已經在另一個線程,因爲你使用「PulseAll」來弱化線程。
E.g.
public void StartQueueHandler()
{
new Thread(()=>StartWorker).Start();
}
private int[] Dequeue()
{
lock(_locker)
{
while(_taskQ.Count == 0) Monitor.Wait(_locker);
return _taskQ.Dequeue();
}
}
private void StartWorker(object obj)
{
while(_keepProcessing)
{
//Handle thread abort or have another "shot down" mechanism.
int[] work = Dequeue();
//If work should be done in parallel without results.
ThreadPool.QueueUserWorkItem(obj => DoWork(work));
//If work should be done sequential according to the queue.
DoWork(work);
}
}
您是對的,我在許多線程中處理隊列中的任務,並希望添加異步添加元素的功能。謝謝爲您的答覆,但我決定使用「ConcurrentQueue
問題是爲什麼你不想添加該功能? 會發生什麼是你開始一個線程添加一個元素,並且線程再次在幾毫秒內死亡,因爲「添加」一個元素(如果正確)將不會阻止你。不得不啓動一個新線程並啓動它可能需要更長的時間,而不僅僅是同步進行。顯然你身邊的某個地方有一個或多個「線程」,這些線程又會增加一些東西,例如通過用戶點擊一個按鈕或端口上的數據傳入等,但你最有可能在那裏處理。將「Enqueue」方法擴展爲Async不會使您受益。 – Jens 2010-10-27 09:07:07
這不是我的決定,任務是關於這個) – 2010-10-28 07:22:08
您問題中的代碼似乎表明您正試圖實施阻塞隊列。在Queue<T>.Enqueue
之後,我從Monitor.PulseAll
撥打電話。這是發出去隊列線程的正常模式。所以如果是這種情況,那麼最好的選擇是使用.NET 4.0中可用的BlockingCollection
類。
您使用的是什麼版本的.net? – 2010-10-27 08:37:20
我決定使用ConcurrentQueue(新的.NET 4集合) –
2010-10-27 09:05:45