gpt4 book ai didi

c# - 线程安全 FIFO 队列/缓冲区

转载 作者:太空狗 更新时间:2023-10-29 18:18:48 24 4
gpt4 key购买 nike

我需要实现一种任务缓冲区。基本要求是:

  • 在单个后台线程中处理任务
  • 从多个线程接收任务
  • 处理所有收到的任务,即确保在收到停止信号后缓冲区中的缓冲任务被清空
  • 必须保持每个线程接收任务的顺序

我正在考虑使用如下所示的队列来实现它。将不胜感激对实现的反馈。有没有其他更好的想法来实现这样的事情?

public class TestBuffer
{
private readonly object queueLock = new object();
private Queue<Task> queue = new Queue<Task>();
private bool running = false;

public TestBuffer()
{
}

public void start()
{
Thread t = new Thread(new ThreadStart(run));
t.Start();
}

private void run()
{
running = true;

bool run = true;
while(run)
{
Task task = null;
// Lock queue before doing anything
lock (queueLock)
{
// If the queue is currently empty and it is still running
// we need to wait until we're told something changed
if (queue.Count == 0 && running)
{
Monitor.Wait(queueLock);
}

// Check there is something in the queue
// Note - there might not be anything in the queue if we were waiting for something to change and the queue was stopped
if (queue.Count > 0)
{
task = queue.Dequeue();
}
}

// If something was dequeued, handle it
if (task != null)
{
handle(task);
}

// Lock the queue again and check whether we need to run again
// Note - Make sure we drain the queue even if we are told to stop before it is emtpy
lock (queueLock)
{
run = queue.Count > 0 || running;
}
}
}

public void enqueue(Task toEnqueue)
{
lock (queueLock)
{
queue.Enqueue(toEnqueue);
Monitor.PulseAll(queueLock);
}
}

public void stop()
{
lock (queueLock)
{
running = false;
Monitor.PulseAll(queueLock);
}
}

public void handle(Task dequeued)
{
dequeued.execute();
}
}

最佳答案

您实际上可以使用开箱即用的 BlockingCollection 来处理这个问题.

它被设计成有 1 个或多个生产者,以及 1 个或多个消费者。在您的情况下,您将有多个生产者和一个消费者。

当您收到停止信号时,让该信号处理程序

  • 信号生产者线程停止
  • 在 BlockingCollection 实例上调用 CompleteAdding

消费者线程将继续运行,直到所有排队的项目都被移除和处理,然后它会遇到 BlockingCollection 完成的条件。当线程遇到该条件时,它就退出。

关于c# - 线程安全 FIFO 队列/缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12375339/

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