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

    •   Core Data   是 iOS SDK   里的一个很强大的框架,允许程序员 以面向对象 的方式储存和管理数据 .使用 Core Data 框架,程序员可以很轻松有效 地通过面向对象的接口 ...

  2. react项目组件化思考

    三个原则 single store render from top immutable data single store,便于组件之间通信. render from top,因为store就一个,每 ...

  3. HQL 参数绑定、唯一结果、分页、投影总结(下)

    分页: 在用hibernate封装的分页方法前,我们先回顾一下,Oracle里面原生分页做法 --分页查询 --(pageNo-1)*pagesize=起始行 pageNo*pagesize=结束行 ...

  4. HBase之集群状态

    import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.*; import org.apache.had ...

  5. 【更新】【封装必备】封装辅助 - 清理&优化工具 For Win7(IT天空会员专版)

    https://www.itsk.com/thread-353560-1-4.html nqawen 发表于 2015-7-9 17:26:37   本帖最后由 Amz 于 2015-11-25 10 ...

  6. python核心编程第六章练习6-9

    6-9.转换.为练习5-13写一个姊妹函数,接受分钟数,返回小时数和分钟数.总时间不变,并且要求小时尽可能大.[答案]代码如下: #!/usr/bin/env python # translate m ...

  7. 使用Python创建简单的HTTP和FTP服务

    不管工作中还是其他场合,经常会有文件分享的需求,比如自己下了一个4GB的游戏,同事下了一个800MB的软件,其他人如果也需要这些文件,显然直接分享是最快捷.最方便.最环保的方式了,如果再重新下,既浪费 ...

  8. How do I install Adobe Flash on Debian Wheezy?

    aptitude install flashplugin-nonfreeif fail Check your settings in /etc/apt/sources.list. If this is ...

  9. 学习笔记 DataGridView数据导出为Excel

    DataGridView数据导出为Excel   怎样把WinForm下的“DGV”里的绑定数据库后的数据导出到Excel中. 比如:在窗体里有个一“DGV”,DataGridView1,绑定了数据源 ...

  10. 把DataTable中的数据拼接成XML时遇到的问题

    错误信息:System.Web.Services.Protocols.SoapException: System.Web.Services.Protocols.SoapException: Serve ...