博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Quartz.net开源作业调度框架使用详解(转)
阅读量:6901 次
发布时间:2019-06-27

本文共 12756 字,大约阅读时间需要 42 分钟。

前言

quartz.net作业调度框架是伟大组织OpenSymphony开发的quartz scheduler项目的.net延伸移植版本。支持 ,集群,数据库。功能性能强大更不用说。

下载项目文档官网:

项目中需引用:Common.Logging.dll , Common.Logging.Core.dll , Quartz.dll 

下面给大家分解下我最近做的关于计划调度的一个小项目,来辅助理解quartz.net的功能和常用方法。

 

quartz.net的简单用法 -入门

如果你是quartz.net的使用新手,控制台入门这里,建议跟着做下,那么10分钟搞懂quartz.net也是 so easy 的事.

1.创建一个每隔3秒钟执行一次的计划调度

public class RunMain    {        static void Main(string[] args)        {            Console.WriteLine(DateTime.Now.ToString("r"));            //1.首先创建一个作业调度池            ISchedulerFactory schedf = new StdSchedulerFactory();            IScheduler sched = schedf.GetScheduler();            //2.创建出来一个具体的作业            IJobDetail job = JobBuilder.Create
().Build(); //3.创建并配置一个触发器 ISimpleTrigger trigger = (ISimpleTrigger)TriggerBuilder.Create().WithSimpleSchedule(x=>x.WithIntervalInSeconds(3).WithRepeatCount(int.MaxValue)).Build(); //4.加入作业调度池中 sched.ScheduleJob(job, trigger); //5.开始运行 sched.Start(); Console.ReadKey(); } } public class JobDemo : IJob { ///
/// 这里是作业调度每次定时执行方法 /// ///
public void Execute(IJobExecutionContext context) { Console.WriteLine(DateTime.Now.ToString("r")); } }

Note:1、记下作业调度创建的顺序。2、上述代码执行结果是,每三秒执行一次JobDemo中的Execute,如果程序不停止,无休无止执行到天荒地老,呵呵,扯下蛋啊。

2.改进(丰富调度计划):上一个作业,我想让他每三秒执行一次,一共执行100次,开始执行时间设定在当前时间,结束时间我设定在2小时后,不过100次执行完没2小时候都不再执行。

public class RunMain    {        static void Main(string[] args)        {            Console.WriteLine(DateTime.Now.ToString("r"));            //首先创建一个作业调度池            ISchedulerFactory schedf = new StdSchedulerFactory();            IScheduler sched = schedf.GetScheduler();            //创建出来一个具体的作业            IJobDetail job = JobBuilder.Create
().Build(); //NextGivenSecondDate:如果第一个参数为null则表名当前时间往后推迟2秒的时间点。 DateTimeOffset startTime = DateBuilder.NextGivenSecondDate(DateTime.Now.AddSeconds(1), 2); DateTimeOffset endTime = DateBuilder.NextGivenSecondDate(DateTime.Now.AddHours(2), 3); //创建并配置一个触发器 ISimpleTrigger trigger = (ISimpleTrigger)TriggerBuilder.Create().StartAt(startTime).EndAt(endTime) .WithSimpleSchedule(x=>x.WithIntervalInSeconds(3).WithRepeatCount(100)) .Build(); //加入作业调度池中 sched.ScheduleJob(job, trigger); //开始运行 sched.Start(); Console.ReadKey(); } } public class JobDemo : IJob { ///
/// 这里是作业调度每次定时执行方法 /// ///
public void Execute(IJobExecutionContext context) { Console.WriteLine(DateTime.Now.ToString("r")); } }

3.继续改进(cron-like使用):前两个作业调度都太简单,如果我想在每小时的第10,20,25,26,33,54分钟,每分钟的第1,10,14秒执行一次。那么上面显然是不能满足的。这是我就把cron-like表达式引入进来,以实现各种时间纬度的调用。

public class RunMain    {        static void Main(string[] args)        {            Console.WriteLine(DateTime.Now.ToString("r"));            //首先创建一个作业调度池            ISchedulerFactory schedf = new StdSchedulerFactory();            IScheduler sched = schedf.GetScheduler();            //创建出来一个具体的作业            IJobDetail job = JobBuilder.Create
().Build(); //NextGivenSecondDate:如果第一个参数为null则表名当前时间往后推迟2秒的时间点。 DateTimeOffset startTime = DateBuilder.NextGivenSecondDate(DateTime.Now.AddSeconds(1), 2); DateTimeOffset endTime = DateBuilder.NextGivenSecondDate(DateTime.Now.AddYears(2), 3); //创建并配置一个触发器 ICronTrigger trigger = (ICronTrigger)TriggerBuilder.Create().StartAt(startTime).EndAt(endTime) .WithCronSchedule("1,10,14 10,20,25,26,33,54 * * * ? ") .Build(); //加入作业调度池中 sched.ScheduleJob(job, trigger); //开始运行 sched.Start(); //挂起2天 Thread.Sleep(TimeSpan.FromDays(2)); //2天后关闭作业调度,将不在执行 sched.Shutdown(); Console.ReadKey(); } } public class JobDemo : IJob { ///
/// 这里是作业调度每次定时执行方法 /// ///
public void Execute(IJobExecutionContext context) { Console.WriteLine(DateTime.Now.ToString("r")); } }

基于Quartz.net的作业调度项目详解

最终效果如开篇的第一个图所示。

下面主要说说,作业调度的中怎么定位到具体的作业调度,并给作业调度分组,命名,添加,启动,停止。

首先展示下表结构,项目中我叫作业调度为任务调度。

1、新增作业调度。

///         /// 任务计划        ///         public static IScheduler scheduler = null;        public static IScheduler GetScheduler()        {            if (scheduler != null)            {                return scheduler;            }            else            {                ISchedulerFactory schedf = new StdSchedulerFactory();                IScheduler sched = schedf.GetScheduler();                return sched;            }        } ///         /// 添加任务计划        ///         /// 
public bool AddScheduleJob(WJ_ScheduleEntity m) { try { if (m != null) { if (m.StarRunTime == null) { m.StarRunTime = DateTime.Now; } DateTimeOffset starRunTime = DateBuilder.NextGivenSecondDate(m.StarRunTime, 1); if (m.EndRunTime == null) { m.EndRunTime = DateTime.MaxValue.AddDays(-1); } DateTimeOffset endRunTime = DateBuilder.NextGivenSecondDate(m.EndRunTime, 1); scheduler = GetScheduler(); IJobDetail job = JobBuilder.Create
() .WithIdentity(m.JobName, m.JobGroup) .Build(); ICronTrigger trigger = (ICronTrigger)TriggerBuilder.Create() .StartAt(starRunTime) .EndAt(endRunTime) .WithIdentity(m.JobName, m.JobGroup) .WithCronSchedule(m.CronStr) .Build(); scheduler.ScheduleJob(job, trigger); scheduler.Start(); StopScheduleJob(m.JobGroup, m.JobName); return true; } return false; } catch (Exception ex) { //DoApplication.WriteLogFile(ex.Message + "\r\n" + ex.StackTrace); return false; } }

Note:1.这里作业调度执行的函数如下。2.上面的WithIdentity(m.JobName, m.JobGroup) ,是给作业调度加入组,和名称,方便我们针对哪一个作业计划,进行启动停止等操作。

 

public class HttpJob : IJob    {        public void Execute(IJobExecutionContext context)        {            ThreadPool.QueueUserWorkItem(delegate(Object o)            {                try                {                    //DoApplication.WriteLogFile(context.JobDetail.Key.Group + "---" + context.JobDetail.Key.Name + "---" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "---" + context.NextFireTimeUtc.Value.DateTime.AddHours(8).ToString("yyyy-MM-dd HH:mm:ss"));                    var sm = new WJ_ScheduleManage().GetScheduleModel(new WJ_ScheduleEntity() { JobGroup = context.JobDetail.Key.Group, JobName = context.JobDetail.Key.Name });                    new WJ_ScheduleManage().UpdateScheduleRunStatus(new WJ_ScheduleEntity() { JobGroup = context.JobDetail.Key.Group, JobName = context.JobDetail.Key.Name,RunStatus=(int)ADJ.Job.Entity.EnumType.JobRunStatus.执行中 });                    ESBRequest req = new ESBRequest(sm.ServiceCode, sm.ApiCode);                    DataResult result = req.Request();                    new WJ_ScheduleManage().UpdateScheduleRunStatus(new WJ_ScheduleEntity() { JobGroup = context.JobDetail.Key.Group, JobName = context.JobDetail.Key.Name, RunStatus = (int)ADJ.Job.Entity.EnumType.JobRunStatus.待运行 });                    if (result.Code == 1)                    {                        #region 加入执行明细                        WJ_ScheduleDetailsEntity dm = new WJ_ScheduleDetailsEntity();                        dm.ActionDescribe = "执行完成:" + result.Message ;                        dm.ActionStep = (int)ADJ.Job.Entity.EnumType.JobStep.执行完成;                        dm.CreateTime = DateTime.Now;                        dm.JobGroup = context.JobDetail.Key.Group;                        dm.JobName = context.JobDetail.Key.Name;                        dm.IsSuccess = 1;                        new WJ_ScheduleManage().AddScheduleDetails(dm);                        #endregion                    }                    else                    {                        #region 加入执行明细                        WJ_ScheduleDetailsEntity dm = new WJ_ScheduleDetailsEntity();                        dm.ActionDescribe = "执行任务计划中,执行计划过程出错."+result.Message;                        dm.ActionStep = (int)ADJ.Job.Entity.EnumType.JobStep.执行任务计划中;                        dm.CreateTime = DateTime.Now;                        dm.JobGroup = context.JobDetail.Key.Group;                        dm.JobName = context.JobDetail.Key.Name;                        dm.IsSuccess = 0;                        new WJ_ScheduleManage().AddScheduleDetails(dm);                        #endregion                    }                    new WJ_ScheduleManage().UpdateScheduleNextTime(new WJ_ScheduleEntity() { JobGroup = context.JobDetail.Key.Group, JobName = context.JobDetail.Key.Name, NextTime = context.NextFireTimeUtc.Value.DateTime.AddHours(8) });                }                catch (Exception ex)                {                    #region 加入执行明细                    WJ_ScheduleDetailsEntity dm = new WJ_ScheduleDetailsEntity();                    dm.ActionDescribe = "执行任务计划中,执行计划过程出错:" + ex.Message + "/r/n" + ex.StackTrace;                    dm.ActionStep = (int)ADJ.Job.Entity.EnumType.JobStep.执行任务计划中;                    dm.CreateTime = DateTime.Now;                    dm.JobGroup = context.JobDetail.Key.Group;                    dm.JobName = context.JobDetail.Key.Name;                    dm.IsSuccess = 0;                    new WJ_ScheduleManage().AddScheduleDetails(dm);                    #endregion                    DoApplication.WriteLogFile(ex.Message + "\r\n" + ex.StackTrace);                }            });        }    }

note:这里执行的Execute方法参数IJobExecutionContext 中,会自动把作业调度的详细信息带过来,作业名称,作业组名,作业下次执行时间,作业执行时间等等,这里的内容也是至关重要的,比如根据作业组,作业名称我们可以从数据库找到相应的作业调度详细,更新操作数据库。

2、针对某个作业计划进行停止,启动。

///         /// 暂停指定任务计划        ///         /// 
public JsonResult StopScheduleJob(string jobGroup, string jobName) { try { scheduler = GetScheduler(); scheduler.PauseJob(new JobKey(jobName, jobGroup)); new WJ_ScheduleManage().UpdateScheduleStatus(new WJ_ScheduleEntity() { JobName = jobName, JobGroup = jobGroup, Status = (int)ADJ.Job.Entity.EnumType.JobStatus.已停止 }); return Json(new StatusView() { Status = 0, Msg = "停止任务计划成功!" }, JsonRequestBehavior.AllowGet); } catch (Exception ex) { DoApplication.WriteLogFile(ex.Message + "/r/n" + ex.StackTrace); return Json(new StatusView() { Status = -1, Msg = "停止任务将计划失败!" }, JsonRequestBehavior.AllowGet); } } /// /// 开启指定的任务计划 /// ///
public JsonResult RunScheduleJob(string jobGroup, string jobName) { try { var sm = new WJ_ScheduleManage().GetScheduleModel(new WJ_ScheduleEntity() { JobName = jobName, JobGroup = jobGroup }); AddScheduleJob(sm); sm.Status = (int)ADJ.Job.Entity.EnumType.JobStatus.已启用; new WJ_ScheduleManage().UpdateScheduleStatus(sm); scheduler = GetScheduler(); scheduler.ResumeJob(new JobKey(jobName, jobGroup)); return Json(new StatusView() { Status = 0, Msg = "启动成功!" }, JsonRequestBehavior.AllowGet); } catch (Exception ex) { DoApplication.WriteLogFile(ex.Message + "/r/n" + ex.StackTrace); return Json(new StatusView() { Status = -1, Msg = "启动失败!" }, JsonRequestBehavior.AllowGet); } }

最后注意:

1、这个项目完全使用啦cron-like表达式实现触发器配置,如果你对cron不了解,那么我上篇中有针对cron做介绍讲解,如果你对cron了解而没有一个合适的生成工具,那么入左上方2个群,找我。

2、这个项目部署在IIS中,那么就要设置应用程序池的回收机制为,永不回收,配置下,如果不会配置,入左上方2个群,找我。

 

http://www.cnblogs.com/knowledgesea/p/4930469.html

转载于:https://www.cnblogs.com/softidea/p/4949615.html

你可能感兴趣的文章
第二篇*2、Python字符串格式化
查看>>
正则表达式以过滤特殊字符
查看>>
关于bootstrap
查看>>
【DM642】H.264源代码在DM642上的移植
查看>>
清晰化算法在DSP上的实现
查看>>
图的存储结构(邻接矩阵)
查看>>
Delphi7_Lite_Fullv7.3优化精简全功能版
查看>>
Android笔记之自定义对话框
查看>>
【转】超实用的JavaScript技巧及最佳实践
查看>>
EIGRP高级特性(汇总,偏移列表,SIA,Stub)
查看>>
C# 格式化新招
查看>>
sql server中的left, right, substring在oracle中都用substr实现
查看>>
Hackthissite realistic 11解密题后的记录
查看>>
编程之美 第1章 游戏之乐——游戏中碰到的题目(二)
查看>>
一种循环方式
查看>>
ChartControl第一课简短的控件初步设计
查看>>
个人博客作业三:微软小娜APP的案例分析
查看>>
python-玉米(小米)商城作业
查看>>
游戏超写实贴图制作技巧
查看>>
Unity Shader 创建程序纹理贴图
查看>>