gpt4 book ai didi

C#线程处理消息队列

转载 作者:行者123 更新时间:2023-12-03 22:38:02 36 4
gpt4 key购买 nike

我有以下要求-

  1. 接收消息并将其排队的线程。
  2. 处理排队消息的线程。

现在,第二个线程必须始终处于事件状态 - 为此我使用了如下无限 while 循环:

private AutoResetEvent messageReset;
private Queue<byte[]> messageQueue;

//thread 2 method
private void ProcessIncomingMessages()
{
messageReset.WaitOne(); //wait for signal
while(true)
{
if (messageQueue.Count > 0)
{
//processing messages
}
}
}
public void SubmitMessageForProcessing(byte[] message){
messageQueue.Enqueue(message); //enqueue message

// Release the thread
messageReset.Set();
}

现在,这个无限的 while 循环使 CPU 利用率非常高。是否有任何解决方法来降低 CPU 利用率

注意:我无法添加任何 thread.sleep 语句,因为传入的消息将以最短的延迟显示在 UI 上。

最佳答案

只需使用 BlockingCollection而不是 Queue。它是线程安全的,并且会在 Take 上阻塞,直到某个工作人员添加了一个项目:

// Use default constructor to make BlockingCollection FIFO
private BlockingCollection<byte[]> messageQueue = new BlockingCollection<byte[]>();

//thread 2 method
private void ProcessIncomingMessages()
{
while (true)
{
//will block until thread1 Adds a message
byte[] message = messageQueue.Take();

//processing messages
}
}
public void SubmitMessageForProcessing(byte[] message)
{
messageQueue.Add(message); //enqueue message
}

EDIT2:我忘了通过使用 default constructor 来提及这一点BlockingCollection 将是 FIFO。它实际上将使用 ConcurrentQueue 作为项目容器。

如果您希望 BlockingCollection 表现得像 LIFO 集合,您需要传递 IProducerConsumerCollection这对构造函数来说是后进先出。通常的类(class)是 ConcurrentStack


编辑:关于您的 Queue 不是线程安全的一些解释,这可能会导致您当前的代码出现问题。

来自关于 Queue 的 Microsoft 文档:

A Queue can support multiple readers concurrently, as long as the collection is not modified.

这意味着您不能同时从多个线程读取和写入。

请看下面的示例,它也适用于其他建议仅在 while(true) block 中移动 messageReset.WaitOne() 的答案。

  1. SubmitMessageForProcessing 被调用并发出信号 messageReset.Set()
  2. 线程 2 激活并尝试读取数据。
  3. 当线程 2 读取数据时 SubmitMessageForProcessing 被第二次调用。
  4. 现在您同时进行写作和阅读,导致意外行为(通常是某种异常)

关于C#线程处理消息队列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51055488/

36 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com