这里记录下 TaskScheduler 的简单用法。

使用场景:

使用 Task 的时候,大家知道用 TaskFactory.StartNew 可以用来创建一个 Task 。这里如果创建了 3 个,那么这3个 Task 就各自放飞直接运行了。

class Program
{private static TaskFactory _taskFactory;static void Main(string[] args){_taskFactory = new TaskFactory();_taskFactory.StartNew(Func1);_taskFactory.StartNew(Func2);_taskFactory.StartNew(Func3);Console.ReadLine();}static void Func1(){Thread.Sleep(3000);Console.WriteLine("Func1");}static void Func2(){Thread.Sleep(2000);Console.WriteLine("Func2");}static void Func3(){Thread.Sleep(1000);Console.WriteLine("Func3");}
}

结果:

Func3

Func2

Func1

一般情况下没什么大问题,但如果这3个中的每个Task都非常耗CPU或者内存,而计算机又需要预留资源去干别的事情,这就要让3个Task不能同时执行。又或者确实要让某些Task先做,有些后做。这就需要我们自己能够决定Task执行顺序。

怎样达到这样的效果?

答案就是:TaskScheduler,它可以让已经创建好的 Task 去按照特殊的顺序来执行。

就拿上面的场景来举例:

为了节约系统资源,我要让这3个Task单独执行,有一个在执行,其它俩就不能执行。最简单的就是串行执行,这样只需要写一个类继承TaskScheduler:

public class MyTaskScheduler : TaskScheduler, IDisposable
{private static readonly object _mutex = new object();public readonly List<Task> _currentTasks = new List<Task>();private readonly ManualResetEvent[] _schedulerEvents = new ManualResetEvent[2];public override int MaximumConcurrencyLevel => 1;public MyTaskScheduler(){_schedulerEvents[0] = new ManualResetEvent(false);_schedulerEvents[1] = new ManualResetEvent(false);var executionThread = new Thread(ExecutionThread) { Name = "MyThread" };executionThread.SetApartmentState(ApartmentState.MTA);executionThread.IsBackground = true;executionThread.Priority = ThreadPriority.Normal;executionThread.Start(null);}public void Dispose(){_schedulerEvents[1].Set();}private void ExecutionThread(object args){try{while (true){if (!WaitIfEmpty()){break;}Task task;lock (_mutex){task = _currentTasks[0];}try{TryExecuteTask(task);}catch (Exception){throw;}finally{TryDequeue(task);}}}finally{//todo}}private bool WaitIfEmpty(){lock (_mutex){if (_currentTasks.Count == 0){//pause task_schedulerEvents[0].Reset();}}//wait any signal.int id = WaitHandle.WaitAny(_schedulerEvents);// id is item index of _schedulerEventsreturn id == 0;}protected override IEnumerable<Task>? GetScheduledTasks(){lock (_mutex){return _currentTasks.ToArray();}}protected override void QueueTask(Task task){lock (_mutex){_currentTasks.Add(task);if (_currentTasks.Count > 0){// Start task_schedulerEvents[0].Set();}}}protected sealed override bool TryDequeue(Task task){lock (_mutex){var res = _currentTasks.Remove(task);return res;}}protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued){return false;}
}

主函数中只要稍作修改:

static void Main(string[] args)
{var taskScheduler = new MyTaskScheduler();_taskFactory = new TaskFactory(taskScheduler);_taskFactory.StartNew(Func1);_taskFactory.StartNew(Func2);_taskFactory.StartNew(Func3);Console.ReadLine();
}

运行结果:

Func1

Func2

Func3

在MyTaskScheduler 中,我建了一个线程 executionThread,线程方法是一个while循环,一直在监听有没有新的Task过来,有多个Task过来,就按Task创建顺序执行,没有的话 while 就暂停在 waitany 处。

这样的场景,配合 ManualResetEvent 和Task的CancellationTokenSource 非常适合做 带有暂停和取消功能的任务列表。

C# TaskScheduler相关推荐

  1. 通过 TaskScheduler 新建windows计划

    需要引用Microsoft.Win32.TaskScheduler.dll 类库 记得using Microsoft.Win32.TaskScheduler; /// <summary>/ ...

  2. C# - 简单介绍TaskScheduler

    task Scheduler根据定义 The task Scheduler by the definition blurb. "Is the class where the usage co ...

  3. taskscheduler java_java – 针对不同任务的不同taskScheduler

    我正在使用 Spring,我在我的应用程序中有几个@Scheduled类: @Component public class CheckHealthTask { @Scheduled(fixedDela ...

  4. TaskScheduler相关

    目录 1.DAGScheduler与TaskScheduler 2.TaskScheduler与SchedulerBackend 3.任务调度过程总结 1.DAGScheduler与TaskSched ...

  5. 一种简单的可控并发粒度的TaskScheduler的实现

    当我们使用.net 4.0中的任务并行库的时候,有时候我们是需要自己控制并发粒度(调度线程数)的,这个时候往往就需要我们自己写TaskScheduler了,一个简单的实现如下: View Code p ...

  6. java scheduletask_spring中定时任务taskScheduler的详细介绍

    前言 众所周知在spring 3.0版本后,自带了一个定时任务工具,而且使用简单方便,不用配置文件,可以动态改变执行状态.也可以使用cron表达式设置定时任务. 被执行的类要实现Runnable接口 ...

  7. spark学习-63-源代码:schedulerBackend和taskScheduler的创建(1)-local

    文章目录 2.根据master生成不同的SchedulerBackend 3.先看看local模式的 local模式下任务的提交与执行过程 测试代码 // 本地模式运行,便于测试val sparkCo ...

  8. 18 TaskScheduler任务调度器抽象基类——Live555源码阅读(一)任务调度相关类

    这是Live555源码阅读的第二部分,包括了任务调度相关的三个类.任务调度是Live555源码中很重要的部分. 本文由乌合之众 lym瞎编,欢迎转载 http://www.cnblogs.com/ol ...

  9. TaskScheduler一个.NET版任务调度器

    TaskScheduler是一个.net版的任务调度器.概念少,简单易用. 支持SimpleTrigger触发器,指定固定时间间隔和执行次数: 支持CronTrigger触发器,用强大的Cron表达式 ...

  10. 《深入理解Spark:核心思想与源码分析》——SparkContext的初始化(叔篇)——TaskScheduler的启动...

    <深入理解Spark:核心思想与源码分析>一书前言的内容请看链接<深入理解SPARK:核心思想与源码分析>一书正式出版上市 <深入理解Spark:核心思想与源码分析> ...

最新文章

  1. 判断数组里面的下标是否等于一个字符串
  2. 一行代码发一篇 ICML?
  3. .net Core学习笔记:Windows环境搭建
  4. 吴恩达机器学习(第四章)——多变量线性回归
  5. 提升Web用户体验的71个设计要点
  6. pat天梯赛L1-055. 谁是赢家
  7. centos7无法使用ifconfig且无法上网
  8. linux环境下vim创建java文件,并编译运行
  9. 浏览器直接访问Linux云服务器下的文件
  10. mysql @符号_MySQL 数值类型
  11. python实现web服务器_python实现web服务器
  12. 计算机 图论基础知识,计算机基础知识
  13. [postgresql]postgresql自定义函数查询ETL作业依赖的实例
  14. 《Effective Python 2nd》——元类与属性
  15. OI树上问题 简单学习笔记
  16. MySQL-第十四篇事务管理
  17. 6U-VPX 高速固态存储板卡—— 外挂2片DDR3,8GB/s带宽,存储容量16TB (KU085)
  18. 一种实现ISA/IEC 62443操作技术标准的零信任应用简化模型
  19. Maya2018基础(一)通用设置与建模基础与常用快捷键
  20. 【读书笔记】《贫穷的本质》- [印度] Abhijit Banerjee / [法] Esther Duflo

热门文章

  1. ramos一键处理多合一_【RAMOS一键批处理多合一 V4.0】在线制作P驱R驱F驱内存系统工具【win系列通用】...
  2. 预测疾病风险参考文章
  3. JQuery方法带回调函数
  4. LAMP坏境和LNMP环境安装Nagios4.1.1和基本配置
  5. 鸿蒙os2.0开机动画,前沿讯息:鸿蒙OS 2.0手机开机画面演示
  6. 网易教程python_Python抓取网易云专辑图详细教程
  7. 带你了解5个幽灵攻击与编译器中的消减方法
  8. 目前为止从四川地震捐款中没有三星和诺基亚
  9. Arduino ESP8266 For EEPROM数据存储示例
  10. rhcsa(文件权限,管理linux的联网,软件包)