C# TaskScheduler
这里记录下 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相关推荐
- 通过 TaskScheduler 新建windows计划
需要引用Microsoft.Win32.TaskScheduler.dll 类库 记得using Microsoft.Win32.TaskScheduler; /// <summary>/ ...
- C# - 简单介绍TaskScheduler
task Scheduler根据定义 The task Scheduler by the definition blurb. "Is the class where the usage co ...
- taskscheduler java_java – 针对不同任务的不同taskScheduler
我正在使用 Spring,我在我的应用程序中有几个@Scheduled类: @Component public class CheckHealthTask { @Scheduled(fixedDela ...
- TaskScheduler相关
目录 1.DAGScheduler与TaskScheduler 2.TaskScheduler与SchedulerBackend 3.任务调度过程总结 1.DAGScheduler与TaskSched ...
- 一种简单的可控并发粒度的TaskScheduler的实现
当我们使用.net 4.0中的任务并行库的时候,有时候我们是需要自己控制并发粒度(调度线程数)的,这个时候往往就需要我们自己写TaskScheduler了,一个简单的实现如下: View Code p ...
- java scheduletask_spring中定时任务taskScheduler的详细介绍
前言 众所周知在spring 3.0版本后,自带了一个定时任务工具,而且使用简单方便,不用配置文件,可以动态改变执行状态.也可以使用cron表达式设置定时任务. 被执行的类要实现Runnable接口 ...
- spark学习-63-源代码:schedulerBackend和taskScheduler的创建(1)-local
文章目录 2.根据master生成不同的SchedulerBackend 3.先看看local模式的 local模式下任务的提交与执行过程 测试代码 // 本地模式运行,便于测试val sparkCo ...
- 18 TaskScheduler任务调度器抽象基类——Live555源码阅读(一)任务调度相关类
这是Live555源码阅读的第二部分,包括了任务调度相关的三个类.任务调度是Live555源码中很重要的部分. 本文由乌合之众 lym瞎编,欢迎转载 http://www.cnblogs.com/ol ...
- TaskScheduler一个.NET版任务调度器
TaskScheduler是一个.net版的任务调度器.概念少,简单易用. 支持SimpleTrigger触发器,指定固定时间间隔和执行次数: 支持CronTrigger触发器,用强大的Cron表达式 ...
- 《深入理解Spark:核心思想与源码分析》——SparkContext的初始化(叔篇)——TaskScheduler的启动...
<深入理解Spark:核心思想与源码分析>一书前言的内容请看链接<深入理解SPARK:核心思想与源码分析>一书正式出版上市 <深入理解Spark:核心思想与源码分析> ...
最新文章
- 判断数组里面的下标是否等于一个字符串
- 一行代码发一篇 ICML?
- .net Core学习笔记:Windows环境搭建
- 吴恩达机器学习(第四章)——多变量线性回归
- 提升Web用户体验的71个设计要点
- pat天梯赛L1-055. 谁是赢家
- centos7无法使用ifconfig且无法上网
- linux环境下vim创建java文件,并编译运行
- 浏览器直接访问Linux云服务器下的文件
- mysql @符号_MySQL 数值类型
- python实现web服务器_python实现web服务器
- 计算机 图论基础知识,计算机基础知识
- [postgresql]postgresql自定义函数查询ETL作业依赖的实例
- 《Effective Python 2nd》——元类与属性
- OI树上问题 简单学习笔记
- MySQL-第十四篇事务管理
- 6U-VPX 高速固态存储板卡—— 外挂2片DDR3,8GB/s带宽,存储容量16TB (KU085)
- 一种实现ISA/IEC 62443操作技术标准的零信任应用简化模型
- Maya2018基础(一)通用设置与建模基础与常用快捷键
- 【读书笔记】《贫穷的本质》- [印度] Abhijit Banerjee / [法] Esther Duflo
热门文章
- ramos一键处理多合一_【RAMOS一键批处理多合一 V4.0】在线制作P驱R驱F驱内存系统工具【win系列通用】...
- 预测疾病风险参考文章
- JQuery方法带回调函数
- LAMP坏境和LNMP环境安装Nagios4.1.1和基本配置
- 鸿蒙os2.0开机动画,前沿讯息:鸿蒙OS 2.0手机开机画面演示
- 网易教程python_Python抓取网易云专辑图详细教程
- 带你了解5个幽灵攻击与编译器中的消减方法
- 目前为止从四川地震捐款中没有三星和诺基亚
- Arduino ESP8266 For EEPROM数据存储示例
- rhcsa(文件权限,管理linux的联网,软件包)