我们经常会遇到生产者消费者模式,比如前端各种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. 如何在windows10环境下安装Pytorch-0.4.1版本

    开始是按照教程:https://blog.csdn.net/xiangxianghehe/article/details/80103095 安装了Pytorch0.4.0,但是安装后发现在import ...

  2. vRO 7 添加RestHost证书报错

    报错类似的错误: Cannot execute request: ; java.security.cert.CertificateException: Certificates does not co ...

  3. 1.linux源码安装nginx

    从官网下载nginx.tar.gz源码包 拷贝至Linux系统下进行解压 tar -zxvf nginx.tar.gz 进入解压后的目录,需要./configure,此步骤会报多个错,比如没有安装gc ...

  4. Apollo和分布式配置

    传统配置文件有什么缺点 如果修改了配置文件,需要重新打包发布,而且每个环境变量配置文件复杂. 分布式配置中心 将配置文件注册到配置中心平台上,可以使用分布式配置中心实时更新配置文件,统一管理,不需要重 ...

  5. tensorFlow 神经网络2

    learnrate 太大容易跑飞,设置激活函数 可以一定程度上增加learnrate,不跑飞 self.saver = tf.train.Saver() 和 self.init_variable = ...

  6. HBase-存储-写路径

    写路径 当用户向HRegionServer发起put请求时,其会将请求交给对应的HRegion实例来处理.第一步是要决定数据是否需要写到由HLog类实现的预写日志中.WAL是标准的Hadoop Seq ...

  7. HBase-存储-概览

    概览 HBase主要处理两种文件:一种是预写日志(Write-Ahead Log,WAL),另一种是实际的数据文件.这两种文件主要由HRegionServer管理.在某些情况下,HMaster也可以进 ...

  8. Caused by: org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'company' in 'class java.lang.String'

    Caused by: org.apache.ibatis.reflection.ReflectionException: There is no getter for property named ' ...

  9. djang-分页

    分页 views from django.shortcuts import render,HttpResponse # Create your views here. from app01.model ...

  10. jsp:jstl标签库国际化 fmt

    首先资源文件目录是:src/man/sources (这是它默认的资源文件) i18n_en_US.properties文件内容 copyright=Copyright \u00A9 2013 lan ...