从C#中的ConcurrentQueue中排队对象

嘿,我正在尝试在C#中为异步服务器实现ConcurrentQueue。 收到完整的消息后,项目将排队。 为了使消息出列,我正在制作少量线程来执行出列和服务请求的工作。 这是不够的,因为每个线程都使用while循环,这显然会消耗相当多的处理器时间。

有人知道一种在需要时出列消息但不消耗这么多处理时间的方法。

{ ... for (int i = 0; i < 3; i++) { Thread t = new Thread(new ThreadStart(startParsingMessages)); t.Start(); } ... } private void startParsingMessages() { QueueContainer dequeued = null; Console.WriteLine("Trying"); while (true) { if (queue.TryDequeue(out dequeued)) { Console.WriteLine("processing queue"); ProcessMessage(dequeued.socket, dequeued.message); } } } 

而不是直接使用ConcurrentQueue ,您是否尝试将其包装在BlockingCollection ? 然后你可以使用TryTake(out T, TimeSpan)等。我相信这是预期的用途:并发集合本身通常就在那里你可以选择阻塞集合的工作方式。

当然,这不一定是这些集合的唯一用途,但特别是对于ConcurrentQueue ,生产者/消费者队列场景是最常见的 – 此时BlockingCollection是使其变得容易的方法做正确的事。

在并发编程中有一个非常清楚的模式叫做Parallel Producer / Consumer模式。 本文可能有助于解决您的一些问题。 http://blogs.msdn.com/b/csharpfaq/archive/2010/08/12/blocking-collection-and-the-producer-consumer-problem.aspx

您可以使用静态锁定对象让线程等待,然后在准备好处理某些内容时对其进行脉冲。

 static readonly object queueLock = new object(); // Threads that enqueue an object void QueueMessage() { lock (queueLock) { queue.Enqueue(obj); Monitor.Pulse(queueLock); } } // Thread dequeuer private void startParsingMessages() { QueueContainer dequeued = null; Console.WriteLine("Trying"); while (true) { lock(queueLock) { if (!queue.TryDequeue(out dequeued)) { Console.WriteLine("No object to dequeue, waiting..."); // Threads will wait here and only one will be released when .Pulse()d Monitor.Wait(queueLock); dequeued = queue.Dequeue(); } if (dequeued != null) { Console.WriteLine("processing queue"); ProcessMessage(dequeued.socket, dequeued.message); } } } } 

请记住,随着分支越多,这可能会变得非常复杂,但它的要点是,您锁定一个公共对象并调用Monitor.Wait等待一个对象为Pulse d。 当发生这种情况时,只有一个等待它的线程将被释放。 如果你将许多对象排入队列并希望它们全部运行,你可以调用Monitor.PulseAll ,它将释放所有在对象上等待的线程。