zoukankan      html  css  js  c++  java
  • 实现一个双缓冲队列(二)

    上一篇(http://www.cnblogs.com/cqgis/p/6403262.html)实现了一个双缓冲队列的例子,我们把消费者的方法直接写到了队例里,为了达到更好的复用,这一篇分享一个封装的泛型类

         /// <summary>
        /// 双缓冲队列
        /// </summary>
        /// <typeparam name="T"></typeparam>
        public class DoubleBufferedQueue<T> : IDisposable
        {
            private readonly int _millisecond;
    
            /// <summary>
            /// 
            /// </summary>
            private readonly Queue<T> _queue1 = new Queue<T>();
            private readonly Queue<T> _queue2 = new Queue<T>();
    
            private readonly ManualResetEvent _equeueLock = new ManualResetEvent(true);
            private readonly ManualResetEvent _dequeuelock = new ManualResetEvent(false);
    
            private readonly AutoResetEvent _autoReset = new AutoResetEvent(true);
    
    
            private volatile Queue<T> _currentQueue;
            private readonly BackgroundWorker _backgroundWorker;
    
            /// <summary>
            /// 双缓冲队列
            /// </summary>
            /// <param name="millisecond">消费者线程处理一批后,需要延时的时间,实现定时间隔操作</param>
            public DoubleBufferedQueue(int millisecond = 0)
            {
                _millisecond = millisecond;
                _currentQueue = _queue1;
    
                _backgroundWorker = new BackgroundWorker();
                _backgroundWorker.DoWork += BackgroundWorker_DoWork;
                _backgroundWorker.RunWorkerAsync();
            }
    
            /// <summary>
            /// 消息者处理方法
            /// </summary>
            public Action<Queue<T>> ConsumerAction { get; set; }
    
    
            private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
            {
                while (true)
                {
                    var readQueue = this.GetDequeue();
                    ConsumerAction?.Invoke(readQueue);
    
                    if (_millisecond > 0)
                        Thread.Sleep(TimeSpan.FromMilliseconds(_millisecond));
                }
                // ReSharper disable once FunctionNeverReturns
            }
    
            public void Equeue(T item, Action<T> action = null)
            {
                this._dequeuelock.WaitOne();
                this._equeueLock.Reset();
    
                _currentQueue.Enqueue(item);
                action?.Invoke(item);
                _equeueLock.Set();
                _autoReset.Set();
            }
    
            private Queue<T> GetDequeue()
            {
                this._autoReset.WaitOne();  //这个信号量是保证在没有成员入队列的时间,不进行其它操作
    
                this._dequeuelock.Reset();  //注意两把锁的顺序,不然会造成死锁的问题
                this._equeueLock.WaitOne();
    
                var readQueue = _currentQueue;
                _currentQueue = (_currentQueue == _queue1) ? _queue2 : _queue1;
    
                this._dequeuelock.Set();
                return readQueue;
            }
    
            public void Dispose()
            {
                _dequeuelock.Reset();
    
                ConsumerAction?.Invoke(_queue1);
                ConsumerAction?.Invoke(_queue2);
                 
                _backgroundWorker?.Dispose();
            }
        }
    

      在调用的时候,指定ConsumerAction即可。

  • 相关阅读:
    css3-13 如何改变文本框的轮廓颜色
    css3-13 css3的3D动画如何实现
    poj 2565 Ants (KM+思维)
    C语言功能 --C
    jQuery简要dom操作
    最近ubuntu 14.04 cpu高入住故障排除
    spring framework 4 源代码阅读器(1) --- 事前准备
    基于Haar特征Adaboost人脸检测级联分类
    ZOJ-3652-Maze(BFS)
    设计模式
  • 原文地址:https://www.cnblogs.com/cqgis/p/6439027.html
Copyright © 2011-2022 走看看