我们经常会遇到生产者消费者模式,比如前端各种UI操作事件触发后台逻辑等。在这种典型的应用场景中,我们可能会有4个业务处理逻辑(下文以P代表生产者,C代表消费者):

1. FIFO(先进先出)
     P产生1,2,3,4,5,6,3,2
     C处理顺序应为1,2,3,4,5,6,3,2
2.LIFO(后进先出)
     P产生1,2,3,4,5,6,3,2
     C处理顺序应为2,3,6,5,4,3,2,1
3.Dynamic FIFO(我定义为:去掉相同数据的FIFO, 如果产生的数据队列里已经有相同数据,后进的数据优先级高)
     P产生1,2,3,4,5,6,3,2
     C处理顺序为1,4,5,6,3,2
4.Dynamic LIFO(我定义为:去掉相同数据的LIFO, 如果产生的数据栈里已经有相同数据,后进的数据优先级高)
     P产生1,2,3,4,5,6,3,2
     C处理顺序为2,3,6,5,4,1
     
1,2情况为基本处理逻辑,3,4可能和我们实际场景有关系(包括:判断相同的逻辑可能不同、已存在和后续数据哪个优先级高)
C#中有个Task类进行异步操作,我们可以通过TaskScheduler类进行任务调度,实现上述的4种基本场景。
定义上述4种场景的通用接口以及其遍历类
public interface IScheduler : IEnumerable<Task >
    {
        void Add (Task t);
        void Remove (Task t);
        int Count { get; }
        Task this [int index] { get; set ; }
    }
    public class SchedulerEnumerator : IEnumerator< Task>
    {
        private IScheduler _collection;
        private int _currentIndex;
        private Task _currentTask;
        public SchedulerEnumerator (IScheduler collection)
        {
            _collection = collection ;
            _currentIndex = -1;
            _currentTask = default (Task);
        }
        public bool MoveNext()
        {
            //Avoids going beyond the end of the collection.
            if (++_currentIndex >= _collection. Count)
            {
                return false ;
            }
            else
            {
                // Set current box to next item in collection.
                _currentTask = _collection [_currentIndex];
            }
            return true ;
        }
        public void Reset() { _currentIndex = -1; }
        void IDisposable .Dispose() { }
        public Task Current
        {
            get { return _currentTask; }
        }
        object IEnumerator .Current
        {
            get { return Current; }
        }
    }
实现我们自己的任务调度类模板,可以通过T传递我们想要的队列类型
 public class TaskSchedulerBase <T> : TaskScheduler
        where T : IScheduler , new ()
    {
        private Thread _processThread;
        private readonly object _lock = new object ();
        public TaskSchedulerBase()
        {
            _processThread = new Thread (this.Process);
        }
        private void Process()
        {
            lock (_lock)
            {
                var tasks = GetScheduledTasks();
                if (null != tasks)
                {
                    foreach (var t in tasks)
                    {
                        TryExecuteTask(t);
                        TryDequeue(t);
                    }
                }
            }
        }
        protected override void QueueTask( Task task)
        {
            lock (_lock)
            {
                Scheduler.Add(task);
                if (_processThread.ThreadState.Equals(ThreadState .Stopped))
                {
                    _processThread = new Thread (Process);
                }
                if (!_processThread.IsAlive
                    && !_processThread.ThreadState.Equals( ThreadState.Running))
                {
                    try
                    {
                        _processThread.Start();
                    }
                    catch (System.Exception )
                    {
                        if (!_processThread.ThreadState.Equals(ThreadState .Running))
                        {
                            _processThread = new Thread (Process);
                            _processThread.Start();
                        }
                    }
                }
            }
        }
        protected override bool TryDequeue( Task task)
        {
            Scheduler.Remove(task);
            return true ;
        }
        protected override IEnumerable< Task> GetScheduledTasks()
        {
            return Scheduler.ToArray();
        }
        protected override bool TryExecuteTaskInline( Task task, bool taskWasPreviouslyQueued)
        {
            if (taskWasPreviouslyQueued)
            {
                if (TryDequeue(task))
                {
                    return base .TryExecuteTask(task);
                }
                else
                {
                    return false ;
                }
            }
            else
            {
                return base .TryExecuteTask(task);
            }
        }
        private readonly T _scheduler = new T();
        public T Scheduler
        {
            get
            {
                return _scheduler;
            }
        }
    }

实现4种队列
     1.FIFO
     
 public class QueueScheduler : IScheduler
    {
        protected Queue <Task> _queue;
        public QueueScheduler ()
        {
            _queue = new Queue< Task>();
        }
        public void Add( Task t )
        {
            if (!Contains (t))
            {
                _queue.Enqueue (t);
            }
        }
        public void Remove( Task t )
        {
            _queue.Dequeue ();
        }
        public bool Contains( Task t )
        {
            bool found = false;
            foreach (var task in _queue )
            {
                if (t .AsyncState != null && t .AsyncState. Equals(task .AsyncState))
                {
                    found = true ;
                    break;
                }
            }
            return found ;
        }
        public bool Contains( Task t , EqualityComparer< Task> comp )
        {
            throw new NotImplementedException();
        }
        public IEnumerator <Task> GetEnumerator()
        {
            return new SchedulerEnumerator( this);
        }
        IEnumerator IEnumerable .GetEnumerator()
        {
            return new SchedulerEnumerator( this);
        }
        public int Count
        {
            get { return _queue. Count; }
        }
        public Task this[ int index]
        {
            get { return (Task) _queue.ToArray ()[index]; }
            set { _queue .ToArray()[index] = value; }
        }
    }

     2.LIFO
public class StackScheduler : IScheduler
    {
        protected Stack <Task> _stack;
        public StackScheduler ()
        {
            _stack = new Stack< Task>();
        }
        public void Add( Task t )
        {
            if (!Contains (t))
            {
                _stack.Push (t);
            }
        }
        public void Remove( Task t )
        {
            _stack.Pop ();
        }
        public bool Contains( Task t )
        {
            bool found = false;
            foreach (var task in _stack )
            {
                if (t .AsyncState != null && t .AsyncState. Equals(task .AsyncState))
                {
                    found = true ;
                    break;
                }
            }
            return found ;
        }
        public bool Contains( Task t , EqualityComparer< Task> comp )
        {
            throw new NotImplementedException();
        }
        public IEnumerator <Task> GetEnumerator()
        {
            return new SchedulerEnumerator( this);
        }
        IEnumerator IEnumerable .GetEnumerator()
        {
            return new SchedulerEnumerator( this);
        }
        public int Count
        {
            get { return _stack. Count; }
        }
        public Task this[ int index]
        {
            get { return (Task) _stack.ToArray ()[index]; }
            set { _stack .ToArray()[index] = value; }
        }
    }

     3.Dynamic FIFO
public class DynamicQueueScheduler : IScheduler
    {
        protected List <Task> _queue;
        public DynamicQueueScheduler ()
        {
            _queue = new List< Task>();
        }
        public virtual void Add(Task t)
        {
            Task oldTask = null;
            if (Contains (t, out oldTask ))
            {
                _queue.Remove (oldTask);
            }
  
            _queue.Add (t);
        }
        public virtual void Remove(Task t)
        {
            _queue.Remove (t);
        }
        public virtual bool Contains(Task t)
        {
            Task oldTask = null;
            bool found = Contains( t, out oldTask);
            return found ;
        }
        public virtual bool Contains(Task t, out Task oldTask)
        {
            bool found = false;
            oldTask = null ;
            foreach (var task in _queue )
            {
                if (t .AsyncState != null && t .AsyncState. Equals(task .AsyncState))
                {
                    oldTask = task ;
                    found = true ;
                    break;
                }
            }
            return found ;
        }
        public virtual bool Contains(Task t, EqualityComparer<Task > comp)
        {
            throw new NotImplementedException();
        }
        public IEnumerator <Task> GetEnumerator()
        {
            return new SchedulerEnumerator( this);
        }
        IEnumerator IEnumerable .GetEnumerator()
        {
            return new SchedulerEnumerator( this);
        }
        public int Count
        {
            get { return _queue. Count; }
        }
        public Task this[ int index]
        {
            get { return (Task) _queue[index]; }
            set { _queue [index] = value; }
        }
    }

     4.Dynamic LIFO
 public class DynamicStackScheduler : IScheduler
    {
        protected List <Task> _queue;
        public DynamicStackScheduler ()
        {
            _queue = new List< Task>();
        }
        public void Add( Task t )
        {
            Task oldTask = null;
            if (Contains (t, out oldTask ))
            {
                _queue.Remove (oldTask);
            }
  
            _queue.Insert (0,t);
        }
        public void Remove( Task t )
        {
            _queue.Remove (t);
        }
        public bool Contains( Task t )
        {
            Task oldTask = null;
            bool found = Contains( t, out oldTask);
            return found ;
        }
        public bool Contains( Task t , out Task oldTask )
        {
            bool found = false;
            oldTask = null ;
            foreach (var task in _queue )
            {
                if (t .AsyncState != null && t .AsyncState. Equals(task .AsyncState))
                {
                    oldTask = task ;
                    found = true ;
                    break;
                }
            }
            return found ;
        }
        public bool Contains( Task t , EqualityComparer< Task> comp )
        {
            throw new NotImplementedException();
        }
        public IEnumerator <Task> GetEnumerator()
        {
            return new SchedulerEnumerator( this);
        }
        IEnumerator IEnumerable .GetEnumerator()
        {
            return new SchedulerEnumerator( this);
        }
        public int Count
        {
            get { return _queue. Count; }
        }
        public Task this[ int index]
        {
            get { return (Task) _queue[index]; }
            set { _queue [index] = value; }
        }
    }

测试代码
  class Program
    {
        static Queue <int> _queue = new Queue< int>();
        //static TaskFactory _factory = new TaskFactory(new TaskSchedulerBase<QueueScheduler>());
        //static TaskFactory _factory = new TaskFactory(new TaskSchedulerBase<StackScheduler>());
        //static TaskFactory _factory = new TaskFactory(new TaskSchedulerBase<DynamicQueueScheduler>());
        //static TaskFactory _factory = new TaskFactory(new TaskSchedulerBase<DynamicStackScheduler>());
        static TaskFactory _factory = new TaskFactory (new TaskSchedulerBase<DynamicQueueScheduler >());
        static void Main( string[] args )
        {
            var thread1 = new Thread(Producer );
            var thread2 = new Thread(Consumer );
            thread1.Start ();
            thread2.Start ();
            Console.ReadKey ();
        }
        static void Producer()
        {
            for (int i = 0; i < 7; i ++)
            {
                _queue.Enqueue (i);
            }
            _queue.Enqueue (3);
            _queue.Enqueue (2);
        }
        static void Consumer()
        {
            while (true )
            {
                if (_queue .Count > 0)
                {
                    foreach (var i in _queue )
                    {
                        _factory.StartNew ((s) =>
                        {
                            Console.Write ("{0} on thread {1} {2}\n", s, Thread.CurrentThread .ManagedThreadId,
                                          DateTime.Now .ToLongTimeString());
                        }, i);
                    }
                    _queue.Clear ();
                }
                else
                {
                    Thread.Sleep (1);
                }
            }
        }
    }

利用TaskScheduler处理Queue、Stack等类型的操作队列(生产者消费者场景)的更多相关文章

  1. #queue队列 #生产者消费者模型

    #queue队列 #生产者消费者模型 #queue队列 #有顺序的容器 #程序解耦 #提高运行效率 #class queue.Queue(maxsize=0) #先入先出 #class queue.L ...

  2. 第三节: List类型的介绍、生产者消费者模式、发布订阅模式

    一. List类型基础 1.介绍 它是一个双向链表,支持左进.左出.右进.右出,所以它即可以充当队列使用,也可以充当栈使用. (1). 队列:先进先出, 可以利用List左进右出,或者右进左出(Lis ...

  3. python2.0_s12_day9之day8遗留知识(queue队列&生产者消费者模型)

    4.线程 1.语法 2.join 3.线程锁之Lock\Rlock\信号量 4.将线程变为守护进程 5.Event事件 * 6.queue队列 * 7.生产者消费者模型 4.6 queue队列 que ...

  4. 利用J.U.C中的lock和condition实现生产者消费者模式

    package lockTest; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.conc ...

  5. Java多线程15:Queue、BlockingQueue以及利用BlockingQueue实现生产者/消费者模型

    Queue是什么 队列,是一种数据结构.除了优先级队列和LIFO队列外,队列都是以FIFO(先进先出)的方式对各个元素进行排序的.无论使用哪种排序方式,队列的头都是调用remove()或poll()移 ...

  6. Python学习笔记——进阶篇【第九周】———线程、进程、协程篇(队列Queue和生产者消费者模型)

    Python之路,进程.线程.协程篇 本节内容 进程.与线程区别 cpu运行原理 python GIL全局解释器锁 线程 语法 join 线程锁之Lock\Rlock\信号量 将线程变为守护进程 Ev ...

  7. 【Python@Thread】queue模块-生产者消费者问题

    python通过queue模块来提供线程间的通信机制,从而可以让线程分项数据. 个人感觉queue就是管程的概念 一个生产者消费者问题 from random import randint from ...

  8. python多线程编程-queue模块和生产者-消费者问题

    摘录python核心编程 本例中演示生产者-消费者模型:商品或服务的生产者生产商品,然后将其放到类似队列的数据结构中.生产商品中的时间是不确定的,同样消费者消费商品的时间也是不确定的. 使用queue ...

  9. stl容器学习——queue,stack,list与string

    目录 头文件 string 目录部分 1.string的定义及初始化 ① 用一个字符串给另一个字符串赋值 ②用字符串常量对字符串进行赋值 ③ 用n个相同的字符对字符串赋值 2.string的运算符及比 ...

随机推荐

  1. PCIE phy和控制器

    转:https://wenku.baidu.com/view/a13bc1c20722192e4436f617.html 文章中的第11页开始有划分phy和控制器部分....

  2. c++ boost库学习三:实用工具

    noncopyable 大家都知道定义一个空类的时候,它实际包含了构造函数,拷贝构造函数,赋值操作符和析构函数等. 这样就很容易产生一个问题,就是当用户调用A a(“^_^") 或者A c= ...

  3. mysql中的一些操作

    查询mysql中事务提交的情况: show variables like '%commit%'; 可以查看当前autocommit值 在mysql数据库中它的默认值是"on"代表自 ...

  4. MongoDB快速入门(八)- 删除文档

    删除文档 MongoDB 的 remove()方法用于从集合中删除文档.remove()方法接受两个参数.一个是标准缺失,第二是justOne标志 deletion criteria : 根据文件(可 ...

  5. thinkphp 多表事务处理

    try{ $this->user = D('User'); $this->user->startTrans(); //开始事务 $res = $this->user->S ...

  6. Luogu-3222 [HNOI2012]射箭

    几何题,二次函数,化一下式子吧 设二次函数\(y=ax^2+bx\),对于一个线段\((x,y1)\),\((x,y2)\),与他相交的条件是\(y1<=ax^2+bx<=y2\) 对于\ ...

  7. sqoop学习3(数据导入乱码问题)

    sqoop将mysql数据库中数据导入hdfs或hive中后中文乱码问题解决办法 [root@spark1 ~]# vi /etc/my.cnf 修改配置文件 在文件内的[mysqld]和client ...

  8. HDU 2480 Steal the Treasure (并查集+贪心)

    题意:给你n个点,m条边,包括有向边与无向边,每条边都有一个权值.在每个点上都有一个人,他可以走与这个点直接相连的所有边中任意一条边一次,并且得到这个权值,就不能走了,注意这条路也只能被一个人走.问最 ...

  9. Spring初学之Spel初配

    Spel又时候可以方便我们为bean的属性赋值,如下配置文件就是常用的一些使用: <?xml version="1.0" encoding="UTF-8" ...

  10. numpy array或matrix的交换两行

    A[j,:] = A[maxindex,:] # 注意这样是一个很低级的错误!这样只是赋值 我们很容易想起python中的两个值交换一句搞定不用引入中间变量 a, b = b, a 但在numpy的a ...