Checking a Queue Continuously

前端 未结 1 1830
粉色の甜心
粉色の甜心 2021-02-05 15:53

I would like a function to check a Queue for new additions continuously on one thread

Obviously there is the option of a continuous loop with sleeps, but I want somethin

1条回答
  •  臣服心动
    2021-02-05 16:07

    Try the blocking queue: Creating a blocking Queue in .NET?

    The basic idea is that when you call TryDequeue it will block until there is something in the queue. As you can see "beauty" of the blocking queue is that you don't have to poll/sleep or do anything crazy like that... it's the fundamental backbone for a Producer/Consumer pattern.

    My version of the blocking queue is:

    public class BlockingQueue where T : class
    {
        private bool closing;
        private readonly Queue queue = new Queue();
    
        public int Count
        {
            get
            {
                lock (queue)
                {
                    return queue.Count;
                }
            }
        }
    
        public BlockingQueue()
        {
            lock (queue)
            {
                closing = false;
                Monitor.PulseAll(queue);
            }
        }
    
        public bool Enqueue(T item)
        {
            lock (queue)
            {
                if (closing || null == item)
                {
                    return false;
                }
    
                queue.Enqueue(item);
    
                if (queue.Count == 1)
                {
                    // wake up any blocked dequeue
                    Monitor.PulseAll(queue);
                }
    
                return true;
            }
        }
    
    
        public void Close()
        {
            lock (queue)
            {
                if (!closing)
                {
                    closing = true;
                    queue.Clear();
                    Monitor.PulseAll(queue);
                }
            }
        }
    
    
        public bool TryDequeue(out T value, int timeout = Timeout.Infinite)
        {
            lock (queue)
            {
                while (queue.Count == 0)
                {
                    if (closing || (timeout < Timeout.Infinite) || !Monitor.Wait(queue, timeout))
                    {
                        value = default(T);
                        return false;
                    }
                }
    
                value = queue.Dequeue();
                return true;
            }
        }
    
        public void Clear()
        {
            lock (queue)
            {
                queue.Clear();
                Monitor.Pulse(queue);
            }
        }
    }
    

    Many thanks to Marc Gravell for this one!

    0 讨论(0)
提交回复
热议问题