我们经常会遇到生产者消费者模式,比如前端各种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. kubernetes liveness readiness

    Liveness Probe(存活探针):用于判断容器是否存货(running状态),如果LivenessProbe探测到容器不健康,则kubelet将杀掉该容器,并根据容器的重启策略做相应的处理.如 ...

  2. Kubernetes Kubeadm部署集群

    Kubernetes高可用架构 Kubenetes 2个高可用核心 apiserver.etcd etcd:集群数据中心,需要保持高可用,用于存放集群的配置信息.状态信息及Pod等信息.如果数据丢失集 ...

  3. codeforces 155D 质数

    题意:有编号1到n的n台机器,有m次操作,操作为开启或关闭机器,成功开启机器k的条件为k和所有已经开启的机器编号互质. 思路:vis[i]数组存放占领i这个位置的机器编号,因为所有开启的机器的编号互质 ...

  4. 关于IIntelliJ IDEA(2017)安装和破解

    一.下载并安装, IntelliJ IDEA的官网:https://www.jetbrains.com 二.破解. 百度下载一个 JetbrainsCrack-2.6.2.jar 破解补丁.放在你的安 ...

  5. Springmvc跳转路径

    forward转发地址栏不发生变化,redirect跳转地址栏变化,forward能把request域中的参数带给下一个,而redirect不会带过去,但是Springmvc的model虽然是基于re ...

  6. vs2010下创建webservice ----第一天(建立项目,以及不连数据库进行加减乘除)

    Visual Studio 2010默认采用的框架为.NET Framework4,在这个框架中已找不到直接创建WebService的模板方式了.但VS2010可以创建WebService是毋庸置疑的 ...

  7. vc 自删除

    // delself.cpp : 定义控制台应用程序的入口点.// #include "stdafx.h"#include <windows.h>#include &l ...

  8. 【转】Oracle中插入和取出图片(用BLOB类型)

    原文地址:http://czllfy.iteye.com/blog/66737 其他参考资料地址:http://lavasoft.blog.51cto.com/62575/321882/ 要在orac ...

  9. Q&A:string、vector、iterator、bitset

    细节要点 getline(cin,string)与cin>>string 在VS2013中通过输入换行符\n,对getline以及cin的用法进行测试,但是并没有像文中所述遇到换行符停止读 ...

  10. CentOS 6.6 中 mysql_5.6 主从数据库配置

    [mysql5.6 主从复制] 1.配置主从节点的服务配置文件 1.1.配置master节点 [mysqld] binlog-format=row log-bin=master-bin log-sla ...