使用AutoResetEvent信号实现生产者消费者队列

来源:互联网 发布:网络打印机维修 编辑:程序博客网 时间:2024/06/09 22:49

使用AutoResetEvent信号实现生产者消费者队列:

主程序作为生产者,添加工作任务;

工作者线程作为消费者,处理工作队列中的任务。


说明:

AutoResetEvent信号:使线程收到信号时,解除阻塞一次。

代码:

namespace ConsoleApplication1{    class Program    {        static void Main(string[] args)        {            //使用using:在using作用域结束时调用ProducerConsumerQueue的析构方法dispose,释放资源            using (ProducerConsumerQueue _pcq = new ProducerConsumerQueue())            {                _pcq.EnQueue("开始工作");                for (int i = 0; i < 10; i++)                {                    _pcq.EnQueue("Work item:" + i);                }                _pcq.EnQueue("工作结束");            }            //调用ProducerConsumerQueue的析构方法dispose,释放资源        }    }    class ProducerConsumerQueue : IDisposable    {        EventWaitHandle _ewh = new AutoResetEvent(false);        Queue<string> _taskQueue = new Queue<string>();        Thread _work;        readonly object _locker = new object();//加锁,实现队列的线程安全        public ProducerConsumerQueue()        {            _work = new Thread(Work);            _work.Start();//启动工作者线程        }        /// <summary>        /// 任务入队列        /// </summary>        /// <param name="task">任务</param>        public void EnQueue(string task)        {            lock (_locker)//加锁,实现线程安全            {                _taskQueue.Enqueue(task);            }                        _ewh.Set();//信号AutoResetEvent:允许线程执行一次        }        void Work()        {            while (true)            {                string task = null;                if (_taskQueue.Count>0)                {                    lock (_locker)//加锁,实现线程安全                    {                        task = _taskQueue.Dequeue();//出队列                    }                                        if (task == null) return;//队列添加一条NULL的任务,表示任务执行完成,退出                }                if (task != null)                {                    Console.WriteLine("Performtask:" + task);                    Thread.Sleep(1000);//模拟任务执行                }                else                    _ewh.WaitOne();//没有任务了,等待信号            }        }                    public void Dispose()        {            EnQueue(null);//结束工作            _work.Join();//等待工作者线程结束             _ewh.Close();//释放等待句柄        }    }}

0 0