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

                }

            }

        }

    }

转:Task任务调度实现生产者消费者模式的更多相关文章

  1. 转:Task任务调度实现生产者消费者模式 (个人理解后文)

    纯属个人愚见.欢迎加入反驳(PiDou). 1.前文大致就是,利用Queue配置的一个TaskFactory任务调度器.实现生产者消费者模式的例子..首先我就试了 第一种 FIFO(先进先出)的配置. ...

  2. Celery 框架学习笔记(生产者消费者模式)

    生产者消费者模式 在实际的软件开发过程中,经常会碰到如下场景:某个模块负责产生数据,这些数据由另一个模块来负责处理(此处的模块是广义的,可以是类.函数.线程.进程等).产生数据的模块,就形象地称为生产 ...

  3. python3全栈开发-多进程的守护进程、进程同步、生产者消费者模式(重点)

    一.守护进程 主进程创建守护进程 其一:守护进程会在主进程代码执行结束后就终止 其二:守护进程内无法再开启子进程,否则抛出异常:AssertionError: daemonic processes a ...

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

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

  5. Java实现多线程生产者消费者模式的两种方法

    生产者消费者模式:生产者和消费者在同一时间段内共用同一存储空间,生产者向空间里生产数据,而消费者取走数据.生产者生产一个,消费者消费一个,不断循环. 第一种实现方法,用BlockingQueue阻塞队 ...

  6. java多线程 生产者消费者模式

    package de.bvb; /** * 生产者消费者模式 * 通过 wait() 和 notify() 通信方法实现 * */ public class Test1 { public static ...

  7. LabVIEW之生产者/消费者模式--队列操作 彭会锋

    LabVIEW之生产者/消费者模式--队列操作 彭会锋 本文章主要是对学习LabVIEW之生产者/消费者模式的学习笔记,其中涉及到同步控制技术-队列.事件.状态机.生产者-消费者模式,这几种技术在在本 ...

  8. Lucene.net站内搜索—4、搜索引擎第一版技术储备(简单介绍Log4Net、生产者消费者模式)

    目录 Lucene.net站内搜索—1.SEO优化 Lucene.net站内搜索—2.Lucene.Net简介和分词Lucene.net站内搜索—3.最简单搜索引擎代码Lucene.net站内搜索—4 ...

  9. MVC异常日志生产者消费者模式记录(异常过滤器)

    生产者消费者模式 定义自己的异常过滤器并注册 namespace Eco.Web.App.Models { public class MyExceptionAttribute : HandleErro ...

随机推荐

  1. C/C++与Matlab混合编程

    Matlab 拥有丰富的功能,编程简单.不过,有些情况下,Matlab程序的执行速度比较慢.C/C++编译执行的程序速度比较快,编程难度上比Matlab要高一些.因此存在一种方案,就是使用Matlab ...

  2. K-邻近算法

    K-邻近算法 采用测量不同特征值之间的距离来进行分类 Ad:精度高,对异常值不敏感,无数据输入假定 Na:计算复杂度高,空间复杂度高 KNN原理 存在样本集,每个数据都存在标签,输入无标签的新数据后, ...

  3. Uiautomator ——API详解

    版权声明:本文出自carter_dream的博客,转载必须注明出处. 转载请注明出处:http://www.cnblogs.com/by-dream/p/4921701.html 简单的例子 以一个简 ...

  4. jsp项目与mysql链接

    因为毕设是地下车库管理系统,所以打算学习jsp进行开发~ 今天主要是[新建网站项目+mysql链接],在此篇之前所做的工作:tomcat服务器配置,mysql数据库的安装与启用(在之后的开发中可以使用 ...

  5. 关于如何来构造一个String类

    今天帮着一位大二的学弟写了一个String的类,后来一想这个技术点,也许不是什么难点,但是还是简单的记录一些吧! 为那些还在路上爬行的行者,剖析一些基本的实现..... 内容写的过于简单,没有涉及到其 ...

  6. Xcode 8 的 Debug 新特性

    Contents OverView Static Analyzer Localizability Instance Cleanup Nullablility Runtime Issue View De ...

  7. ioS基础篇(十九)——UIResponder简析

    UIResponder类定义了对象相应和控制事件的接口,他是UIApplication.UIView的超类,这类的实例通常被称为应答对象. 一.Responder对象 在iOS系统中,能够响应并处理事 ...

  8. iOS基础篇(十三)——UITableView(一)重用机制

    UITableView是app开发中常用到的控件,功能很强大,常用于数据的显示.在学习UITableView使用之前,我们先简单了解一下: 1.UITableView的重用机制 UITableView ...

  9. Python高效编程的19个技巧

    初识Python语言,觉得python满足了我上学时候对编程语言的所有要求.python语言的高效编程技巧让我们这些大学曾经苦逼学了四年c或者c++的人,兴奋的不行不行的,终于解脱了.高级语言,如果做 ...

  10. iOS开发多线程篇—GCD介绍

    iOS开发多线程篇—GCD介绍 一.简单介绍 1.什么是GCD? 全称是Grand Central Dispatch,可译为“牛逼的中枢调度器” 纯C语言,提供了非常多强大的函数 2.GCD的优势 G ...