开发者

How to async add elements to Queue<T> in C#?

开发者 https://www.devze.com 2023-01-21 08:57 出处:网络
public void Enq开发者_如何转开发ueueTask(int[] task) { lock (_locker) { _taskQ.Enqueue(task); Monitor.PulseAll(_locker);
public void Enq开发者_如何转开发ueueTask(int[] task)
{
    lock (_locker)
    {
        _taskQ.Enqueue(task);
        Monitor.PulseAll(_locker);
    }
}

So, here I'm adding elements to my queue and than threads do some work with them.How can I add items to my queue asynchronously?


If you using .net V4 have a look at the new thread safe collections, they are mostly none blocking so will properly avoid the need for an async add.


Since your using Queue<T> (recommended), Queue.Synchronized can't be used.

But besides that I would use the thread pool. But your EnqueueTask method kind of implies that the threading logic is handled outside of your "TaskQueue" class (your method implies that it is a Queue of tasks).

Your implementation also implies that it is not "Here" we wan't to add logic but rather in another place, the code you have there isn't really blocking for long so I would turn things upside down.

It also implies that the thing taking things off the queue is already on another thread since you use "PulseAll" to weak that thread up.

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);
  }
}


Maybe something like this could work:

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

The new thread ensures that your current thread does not block.

Queue.Syncronized handles all locking of the queue. It could be replaced with your locker code, might be better performance.


The code from your question seems to indicate that you are attempting to implement a blocking queue. I make that obseration from the call to Monitor.PulseAll after the Queue<T>.Enqueue. This is the normal pattern for signalling the dequeuing thread. So if that is the case then the best option is to use the BlockingCollection class which is available in .NET 4.0.

0

精彩评论

暂无评论...
验证码 换一张
取 消