Threadsafe FIFO Queue / Buffer

Мне нужно реализовать своего рода буфер задач. Основные требования:

Обрабатывать задачи в одном фоновом потокеПолучать задачи из нескольких потоковОбработать ВСЕ принятые задачи, т.е. убедиться, что из буферизованных задач очищен буфер после получения сигнала остановкиПорядок задач, полученных на поток должен быть сохранен

Я думал о реализации этого с использованием очереди, как показано ниже. Буду признателен за отзыв о реализации. Есть ли другие яркие идеи для реализации такой вещи?

public class TestBuffer
{
    private readonly object queueLock = new object();
    private Queue queue = new Queue();
    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();
    }
}

Ответы на вопрос(5)

Ваш ответ на вопрос