2010-10-27 119 views
3
public void EnqueueTask(int[] task) 
{ 
    lock (_locker) 
    { 
     _taskQ.Enqueue(task); 
     Monitor.PulseAll(_locker); 
    } 
} 

所以,在這裏,我將元素添加到我的隊列中,而不是線程對它們進行一些處理。如何將項目異步添加到隊列中?如何在C#中將隊列添加到隊列<T>?

+0

您使用的是什麼版本的.net? – 2010-10-27 08:37:20

+0

我決定使用ConcurrentQueue (新的.NET 4集合) – 2010-10-27 09:05:45

回答

2

如果你使用.net V4看看新的線程安全集合,他們大多沒有阻塞,所以將適當地避免需要一個異步添加。

+0

ConcurrentQueue 2010-10-27 08:57:51

+0

順便說一句,謝謝:)。我有來自.NET 4的新線程安全集合的書籤,並且您幫助我記住它們) – 2010-10-27 09:07:55

0

也許這樣的事情可以工作:

void AddToQueue(Queue queue, string mess) { 
    var t = new Thread(() => Queue.Synchronized(queue).Enqueue(mess)); 
    t.Start(); 
} 

新線程確保您的當前線程不會阻止。

Queue.Syncronized處理隊列的所有鎖定。 它可以替換你的儲物櫃代碼,可能會有更好的表現。

2

由於您使用隊列<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); 
    } 
} 
+0

您是對的,我在許多線程中處理隊列中的任務,並希望添加異步添加元素的功能。謝謝爲您的答覆,但我決定使用「ConcurrentQueue 」,恕我直言,我最邪惡的方式:) – 2010-10-27 09:01:05

+0

問題是爲什麼你不想添加該功能? 會發生什麼是你開始一個線程添加一個元素,並且線程再次在幾毫秒內死亡,因爲「添加」一個元素(如果正確)將不會阻止你。不得不啓動一個新線程並啓動它可能需要更長的時間,而不僅僅是同步進行。顯然你身邊的某個地方有一個或多個「線程」,這些線程又會增加一些東西,例如通過用戶點擊一個按鈕或端口上的數據傳入等,但你最有可能在那裏處理。將「Enqueue」方法擴展爲Async不會使您受益。 – Jens 2010-10-27 09:07:07

+0

這不是我的決定,任務是關於這個) – 2010-10-28 07:22:08

0

您問題中的代碼似乎表明您正試圖實施阻塞隊列。在Queue<T>.Enqueue之後,我從Monitor.PulseAll撥打電話。這是發出去隊列線程的正常模式。所以如果是這種情況,那麼最好的選擇是使用.NET 4.0中可用的BlockingCollection類。