如何在 C# 中异步添加元素到 Queue<T>?

3
public void EnqueueTask(int[] task)
{
    lock (_locker)
    {
        _taskQ.Enqueue(task);
        Monitor.PulseAll(_locker);
    }
}

所以,我在向队列中添加元素,然后线程对它们进行一些操作。如何异步地向队列添加项目?


你正在使用哪个版本的 .NET? - Ian Ringrose
我决定使用ConcurrentQueue<T>(.NET 4中的新集合)。 - illegal-immigrant
4个回答

2

由于您正在使用Queue<T>(推荐),因此无法使用Queue.Synchronized。

但除此之外,我建议使用线程池。但是您的EnqueueTask方法有点暗示着线程逻辑是在“TaskQueue”类之外处理的(您的方法暗示它是任务队列)。

您的实现还暗示着我们不想在这里添加逻辑,而是在另一个地方,您那里的代码并不真正阻塞很长时间,所以我会颠倒一下事情。

它还意味着从队列中取出东西的东西已经在另一个线程上了,因为您使用“PulseAll”来唤醒该线程。

例如:

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<T>”,在我看来,这是最简单的方法 :) - illegal-immigrant
问题是为什么你想要添加这个功能呢? 你所做的就是启动一个线程来添加一个元素,然后该线程在几毫秒内就会死亡,因为“添加”一个元素(如果正确执行)不会阻塞你。必须启动一个新线程并启动它可能比同步执行更耗时。显然,在外部某个地方,你有一个或多个“线程”,这些线程将依次添加一些东西,例如用户单击按钮或数据进入端口等。但是你最有可能在那里处理它们。将你的“Enqueue”方法扩展为异步方法对你没有好处。 - Jens
这不是我的决定,任务就是关于那个的。 - illegal-immigrant
我正在使用异步委托来异步地向队列中添加项目,然后特殊的添加管理器负责加载PC上的每个核心。 - illegal-immigrant

2
如果您使用的是 .net V4,请查看新的线程安全集合,它们大多数都是非阻塞的,因此可以避免需要异步添加的情况。

顺便说一句,谢谢:)我有.NET 4中新的线程安全集合的书签,你帮我想起了它们。 - illegal-immigrant

0

或许类似这样的代码可以实现:

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

新线程确保当前线程不会被阻塞。

Queue.Syncronized 处理队列的所有锁定。 它可以替换为您的锁定代码,可能会获得更好的性能。


0
从您的问题中的代码似乎表明您正在尝试实现一个阻塞队列。我从调用Queue<T>.Enqueue后的Monitor.PulseAll中做出这个观察。这是向出队线程发出信号的正常模式。因此,如果是这种情况,则最好的选择是使用.NET 4.0中提供的BlockingCollection类。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接