SoFunction
Updated on 2025-03-06

C# uses generic queue Queue to implement production and consumption mode

If production and consumption are imagined as automatic assembly line, production is the material of the assembly line, consumption is the behavior of a certain equipment processing the material, and assembly line is the queue.

Now, we need to write a generic help class that reflects the production and consumption model, such as ProducerConsumer<T>.

This class will definitely maintain a field of Queue<T> type about production and materials, and there will also be a field of consumption and Action<T> type.

In the constructor of the ProducerConsumer class, assign values ​​to fields of Action<T> type and enable threads related to consumption in the background.

The ProducerConsumer class must have a queue-entry method, and it is necessary to ensure that in multi-threading situations, only one production or material enters the queue at the same time.

The ProducerConsumer class also has a method about consumption, and ensures that in multithreading cases, there is only one production or material out of the list at the same time and consumes it.

In addition, when production or materials are out of queue, there may be no production or materials in the queue. At this time, we hope that the thread will block, which needs to be achieved through AutoResetEvent. The general principle of AutoResetEvent is: when production or materials enter the queue, you need to tell AutoResetEvent. When there is no production or materials in the queue for the time being, you also need to tell AutoResetEvent to block the thread.

  //Generics about production and consumption    public class ProducerConsumer&lt;T&gt;
    {
        //The queue used to store producers        private readonly Queue&lt;T&gt;  queue = new Queue&lt;T&gt;();
        //Lock        private readonly object queueLocker = new object();
        //Consumption behavior        private readonly Action&lt;T&gt; consumerAction;
        // When delisting, you need to check whether there are elements in the queue. If not, you need to block        private readonly AutoResetEvent queueWaitHandle = new AutoResetEvent(false);
        public ProducerConsumer(Action&lt;T&gt; consumerAction)
        {
            if (consumerAction == null)
            {
                throw new ArgumentNullException("consumerAction");
            }
             = consumerAction;
            //Open a thread in the background and start consumer producer            new Thread(){IsBackground = true}.Start();
        }
        //Enter the list        public void Enqueue(T item)
        {
            //Make sure that only one producer enters the list at the same time            lock (queueLocker)
            {
                (item);
                //Every time you enter the column, you must set the AutoResetEvent event                ();
            }
        }
        //Consumption Action        private void ConsumeItems()
        {
            while (true)
            {
                T nextItem = default(T);
                //Flag to confirm whether the producer in the queue exists                bool doesItemExist;
                //Make sure that only one producer is out of the list at the same time                lock ()
                {
                    //Check whether the producer in the queue exists first                    doesItemExist =  &gt; 0;
                    if (doesItemExist)
                    {
                        nextItem = ();
                    }
                    
                }
                //If the producer exists, the producer will be consumed                if (doesItemExist)
                {
                    (nextItem);
                }
                else// Otherwise, wait for the producer in the next queue                {
                    ();
                }
                
            }
        }
    }

Client, for multi-threaded situations.

    class Program
    {
        static void Main(string[] args)
        {
            //Instantiate an int type production and consumption instance            var producerConsumer = new ProducerConsumer&lt;int&gt;(i =&gt; ("Consuming" + i));
            Random random = new Random();
            //Open the queue thread            var t1 = new Thread(() =&gt;
            {
                for (int i = 0; i &lt; 100; i++)
                {
                    (i);
                    ((0,5));
                }
            });
            var t2 = new Thread(() =&gt;
            {
                for (int i = 0; i &gt; -100; i--)
                {
                    (i);
                    ((0, 5));
                }
            });
            ();
            ();
            ();
            ();
            (50);
            ();
        }
    }

The above is the entire content of this article. I hope that the content of this article has certain reference value for your study or work. Thank you for your support. If you want to know more about it, please see the following links