C#基于Quartz.NET实现任务调度并部署Windows服务
一、quartz.net介绍
quartz.net是一个强大、开源、轻量的作业调度框架,是 opensymphony 的 quartz api 的.net移植,用c#改写,可用于winform和asp.net mvc、.net core应用中。它灵活而不复杂。你能够用它来为执行一个作业而创建简单的或复杂的作业调度。它有很多特征,如:数据库支持,集群,插件,支持cron-like表达式等等。
官网:
源码:https://github.com/quartznet/quartznet
二、quartz.net用途
一,可以定时发邮件通知。
二 , 电商网站的定时打折活动。(比如规定11月11日 淘宝购买女朋友打八折)
三, 定时对数据更新 或者添加。
四,自己朋友生日。 可以定时发生日祝福。 等等 (我也不一一举例了)
三、quartz.net安装
我使用的vs版本是2017的 选择工具 - nuget包管理 - 管理解决方案的nuget包 输入 quartz.net 安装
还可以通过nuget控制台 通过安装命令
install-package quartz
四、quartz.net实现思路
一:继承并实现ijob接口,在execute 方法中写你要定时执行的事情(切记 )
二:使用quartz创建任务调度核心代码步骤
1、配置quartz,创建工厂,开启调度。
2、创建工作任务
3、创建触发器
4、将任务加入到任务池
三:添加任务,使用topshelf部署windows服务,定时执行
五、代码步骤讲解
一:继承并实现ijob接口,在execute 方法中写你要做的事情(切记 )
1 using quartz.utility; 2 using system; 3 using system.io; 4 using system.threading.tasks; 5 6 namespace quartz.jobwork 7 { 8 public class myjob : ijob 9 { 10 public task execute(ijobexecutioncontext context) 11 { 12 task task = null; 13 try 14 { 15 string filename = "printlog.txt"; 16 streamwriter writer = new streamwriter(filename, true); 17 task = writer.writelineasync(string.format("{0},测试", datetime.now.tolongtimestring())); 18 writer.close(); 19 writer.dispose(); 20 } 21 catch (exception ex) 22 { 23 loghelper.writelog(ex.message.tostring(), ex); 24 } 25 return task; 26 } 27 } 28 }
二:使用quartz创建任务调度核心代码步骤
注:这里提供一个quartzhelper帮助类,直接把以下代码copy过去即可用,只需要重写execute方法即可。quartz3.0及以上的版本是采用的异步,3.0以下的版本没有采用异步,使用方法是一样的
1 using quartz.impl; 2 using system; 3 using system.collections.generic; 4 using system.collections.specialized; 5 using system.linq; 6 using system.text; 7 using system.threading; 8 using system.threading.tasks; 9 10 namespace quartz.utility 11 { 12 public class quartzhelper 13 { 14 static readonly ischeduler _scheduler; 15 static quartzhelper() 16 { 17 var properties = new namevaluecollection(); 18 // 设置线程池 19 properties["quartz.threadpool.type"] = "quartz.simpl.simplethreadpool, quartz"; 20 //设置线程池的最大线程数量 21 properties["quartz.threadpool.threadcount"] = "5"; 22 //设置作业中每个线程的优先级 23 properties["quartz.threadpool.threadpriority"] = threadpriority.normal.tostring(); 24 25 // 远程输出配置 26 properties["quartz.scheduler.exporter.type"] = "quartz.simpl.remotingschedulerexporter, quartz"; 27 properties["quartz.scheduler.exporter.port"] = "555"; //配置端口号 28 properties["quartz.scheduler.exporter.bindname"] = "quartzscheduler"; 29 properties["quartz.scheduler.exporter.channeltype"] = "tcp"; //协议类型 30 31 //创建一个工厂 32 var schedulerfactory = new stdschedulerfactory(properties); 33 //启动 34 _scheduler = schedulerfactory.getscheduler().result; 35 //1、开启调度 36 _scheduler.start(); 37 } 38 /// <summary> 39 /// 时间间隔执行任务 40 /// </summary> 41 /// <typeparam name="t">任务类,必须实现ijob接口</typeparam> 42 /// <param name="seconds">时间间隔(单位:秒)</param> 43 public static async task<bool> executeinterval<t>(int seconds) where t : ijob 44 { 45 //2、创建工作任务 46 ijobdetail job = jobbuilder.create<t>().build(); 47 // 3、创建触发器 48 itrigger trigger = triggerbuilder.create() 49 .startnow() 50 .withsimpleschedule( 51 x =>x.withintervalinseconds(seconds) 52 //x.withintervalinminutes(1) 53 .repeatforever()) 54 .build(); 55 //4、将任务加入到任务池 56 await _scheduler.schedulejob(job, trigger); 57 return true; 58 } 59 60 /// <summary> 61 /// 指定时间执行任务 62 /// </summary> 63 /// <typeparam name="t">任务类,必须实现ijob接口</typeparam> 64 /// <param name="cronexpression">cron表达式,即指定时间点的表达式</param> 65 public static async task<bool> executebycron<t>(string cronexpression) where t : ijob 66 { 67 //2、创建工作任务 68 ijobdetail job = jobbuilder.create<t>().build(); 69 //3、创建触发器 70 icrontrigger trigger = (icrontrigger)triggerbuilder.create() 71 .startnow() 72 .withcronschedule(cronexpression) 73 .build(); 74 //4、将任务加入到任务池 75 await _scheduler.schedulejob(job, trigger); 76 return true; 77 } 78 } 79 }
三:添加任务,topshelf部署windows服务,定时执行
1 namespace quartz 2 { 3 public class program 4 { 5 static void main(string[] args) 6 { 7 string cronexpression = "0 0 8,23 * * ? "; //=>这是指每天的9点和16点执行任务 8 cronexpression = "30 0/1 * * * ?"; 9 //quartzhelper.executebycron<myjob>(cronexpression).wait(); //=>这是调用cron计划方法 10 quartzhelper.executeinterval<myjob>(180).wait(); 11 /* 12 简单说一下cron表达式吧, 13 14 由7段构成:秒 分 时 日 月 星期 年(可选) 15 16 "-" :表示范围 mon-wed表示星期一到星期三 17 "," :表示列举 mon,web表示星期一和星期三 18 "*" :表是“每”,每月,每天,每周,每年等 19 "/" :表示增量:0/15(处于分钟段里面) 每15分钟,在0分以后开始,3/20 每20分钟,从3分钟以后开始 20 "?" :只能出现在日,星期段里面,表示不指定具体的值 21 "l" :只能出现在日,星期段里面,是last的缩写,一个月的最后一天,一个星期的最后一天(星期六) 22 "w" :表示工作日,距离给定值最近的工作日 23 "#" :表示一个月的第几个星期几,例如:"6#3"表示每个月的第三个星期五(1=sun...6=fri,7=sat) 24 25 如果minutes的数值是 '0/15' ,表示从0开始每15分钟执行 26 27 如果minutes的数值是 '3/20' ,表示从3开始每20分钟执行,也就是‘3/23/43’ 28 */ 29 hostfactory.run(x => 30 { 31 x.uselog4net(); 32 //x.service<towncrier>(s => 33 //{ 34 // s.constructusing(name => new towncrier()); 35 // s.whenstarted(tc => tc.start()); 36 // s.whenstopped(tc => tc.stop()); 37 //}); 38 x.runaslocalsystem(); 39 x.setdescription("quartzjob任务定时发送"); 40 x.setdisplayname("quartzjob"); 41 x.setservicename("quartzjob"); 42 43 x.enablepauseandcontinue(); 44 }); 45 console.readkey(); 46 } 47 } 48 }
最后就可以做自己想要做的事情了!
下期讲解使用topshelf部署windows服务!