使用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();//释放等待句柄 } } }