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

使用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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值