Quartz.NET是一个非常强大的作业调度框架,适用于各种定时执行的业务处理等,类似于WINDOWS自带的任务计划程序,其中运用Cron表达式来实现各种定时触发条件是我认为最为惊喜的地方。

Quartz.NET主要用到下面几个类:

IScheduler --调度器

IJobDetail --作业任务

ITrigger --触发器

如果我们自己采用Timer来写类似的定时执行任务程序的话,相应的我们应该有:(以下均为设想,目的是让大家搞清楚Quartz.NET上面三个接口的关系)

ScheduleTimer --Timer,每秒执行一次;

TriggerClass --判断是否需要执行作业任务,ScheduleTimer 每执行一次,就应该新开线程调用TriggerClass成员 NeedExecute方法或属性;

JobClass--具体的作业任务类,TriggerClass,若TriggerClass.NeedExecute返回true,那么就应该执行JobClass成员Execute方法;

好了,有关Quartz.NET的介绍非常之多,我这里不在多说,下面将主要介绍如何实现伪AOP写LOG功能。

AOP不知道,请点击此处了解。

Quartz.NET虽然已经集成了log4net的写日志功能,只需在Config配置好即可,但我觉得框架里面写的日志不符合我的要求,故我需要按照实际业务需要在某些条件才进行写LOG,故才有了这篇文章。

以下是实现了一个Job包裹类,也可以看作是Job的代理类,完整代码如下:

    [DisallowConcurrentExecution]public class JobWraper<TJob> : IJob where TJob : IJob, new(){private static int syncFlag = 0;private IJob jobInner = null;public JobWraper(){jobInner = Activator.CreateInstance<TJob>();}public void Execute(IJobExecutionContext context){if (Interlocked.Increment(ref syncFlag) != 1) return; //忙判断try{jobInner.Execute(context);}catch (Exception ex){Master.WriteMsg(context.JobDetail.Key + "执行异常:" + ex.Message + Environment.NewLine + ex.StackTrace, true, true);}Interlocked.Exchange(ref syncFlag, 0); //解除忙}

代码很简单,一般人都看得懂,我只是说重点:

1.syncFlag静态字段,目的是用来标记是否忙或者不忙,1代表不忙,其它代表忙,Interlocked.Increment与Interlocked.Exchange的用法是原子级的,确保每次只能有一个线程进行操作,类似于SQL中的独占锁,与lock有点相同,但又不同,如果用lock将整个执行都用大括号包起来,那么锁的范围比较广而且不易控制,而Interlocked只需要在需要的时候才独占,而且独占的时间非常短,其他大部份时间都是正常,而且更易可控,这就是我喜欢用他的原因。

2.为什么标记忙与不忙,原因是我必需确保每次执行的业务逻辑能够执行完成,而不要出现未执行完成,下一次的执行点又到了,造成多次甚至重复执行。

2.为什么要包裹,原因是我不想每个Job类里面都写try catch异常捕获及忙与不忙的判断,这样普通类只需专注业务处理即可。至于被包裹的类不一定非要IJob接口,可以自定义各类接口,但一定要有无参构造函数,否则就无法创建包裹的类的实例了。

通过上面的讲解,大家应该都明白了,下面是我为了便于集成管理Job,封装了一个JobManager任务管理类,完整代码如下:(代码比较简单,不再说明)

    public class JobManager{private IScheduler scheduler = null;private int schedulerState = 0;public Dictionary<string, JobWithTrigger> JobTriggers{get;private set;}private IScheduler GetAScheduler(){var stdSchedulerFactory = new StdSchedulerFactory();scheduler = stdSchedulerFactory.GetScheduler();return scheduler;}public JobManager(){scheduler = GetAScheduler();JobTriggers = new Dictionary<string, JobWithTrigger>();}public JobWithTrigger CreateJobWithTrigger<TJob>(string cronExpr, IDictionary<string, object> jobData = null) where TJob : IJob{var jobType = typeof(TJob);string jobTypeName = jobType.Name;if (jobType.IsGenericType){jobTypeName = jobType.GetGenericArguments()[0].Name;}IJobDetail job = null;if (jobData == null)job = JobBuilder.Create<TJob>().WithIdentity(jobTypeName).Build();elsejob = JobBuilder.Create<TJob>().WithIdentity(jobTypeName).UsingJobData(new JobDataMap(jobData)).Build();ITrigger trigger = TriggerBuilder.Create().WithIdentity(jobTypeName + "-Trigger").ForJob(job).StartNow().WithCronSchedule(cronExpr).Build();var jt = new JobWithTrigger(job, trigger);JobTriggers[jt.Key] = jt;return jt;}public void ScheduleJobs(params JobWithTrigger[] jts){if (scheduler.IsShutdown){scheduler = GetAScheduler();}foreach (var jt in jts){scheduler.ScheduleJob(jt.JobDetail, jt.Trigger);}}public void ScheduleJobs(params string[] jtKeys){var jts = JobTriggers.Where(t => jtKeys.Contains(t.Key)).Select(t => t.Value).ToArray();ScheduleJobs(jts);}public void UnscheduleJobs(params TriggerKey[] triggerKeys){scheduler.UnscheduleJobs(triggerKeys.ToList());}public void UnscheduleJobs(params string[] jtKeys){var triggerKeyObjs = JobTriggers.Where(t => jtKeys.Contains(t.Key)).Select(t => t.Value.Trigger.Key).ToArray();UnscheduleJobs(triggerKeyObjs);}public int State{get{return schedulerState;  //0:未开始,1:开始,2:暂停,3:恢复,-1:停止}}[MethodImpl(MethodImplOptions.Synchronized)]public void Start(){if (schedulerState > 0) return;scheduler.Start();schedulerState = 1;Master.WriteMsg("AutoTimingExecSystem程序已启动,所有任务按计划开始执行。", false, true);}[MethodImpl(MethodImplOptions.Synchronized)]public void Stop(){if (schedulerState <= 0) return;scheduler.Clear();scheduler.Shutdown();schedulerState = -1;Master.WriteMsg("AutoTimingExecSystem程序已停止,所有任务停止执行。", false, true);}[MethodImpl(MethodImplOptions.Synchronized)]public void Pause(){if (schedulerState != 1) return;scheduler.PauseAll();schedulerState = 2;Master.WriteMsg("所有任务被取消或暂停执行。", false, true);}[MethodImpl(MethodImplOptions.Synchronized)]public void Resume(){if (schedulerState != 2) return;scheduler.ResumeAll();schedulerState = 1;Master.WriteMsg("所有任务重新恢复执行。", false, true);}}

JobWithTrigger:任务与触发器关联类

    [Serializable]public class JobWithTrigger{public JobWithTrigger(){this.Key = Guid.NewGuid().ToString("N");}public JobWithTrigger(IJobDetail job, ITrigger trigger): this(){this.JobDetail = job;this.Trigger = trigger;}public IJobDetail JobDetail{ get; set; }public ITrigger Trigger{ get; set; }public string JobName{get{return this.JobDetail.Key.Name;}}public string TriggerName{get{return this.Trigger.Key.Name;}}public string Key{get;private set;}}

用法比较简单,示例代码如下:

var jobManager = new JobManager();
var jt=jobManager.CreateJobWithTrigger<JobWraper<TestJob>>("0/5 * * * * ?");//这里面可以将jt的保存或显示到任务界面上...jobManager.ScheduleJobs(JobWithTrigger的KEY数组 或 JobWithTrigger对象)jobManager.Start(); jobManager.Stop();

jobManager支持反复开启与关闭。

本文转自 梦在旅途 博客园博客,原文链接:http://www.cnblogs.com/zuowj/p/6013040.html  ,如需转载请自行联系原作者

关于Quartz.NET作业调度框架的一点小小的封装,实现伪AOP写LOG功能相关推荐

  1. Quartz.NET作业调度框架详解

    Quartz.NET是一个开源的作业调度框架,是OpenSymphony 的 Quartz API的.NET移植,它用C#写成,可用于winform和asp.net应用中.它提供了巨大的灵活性而不牺牲 ...

  2. .NET开源作业调度框架Quartz

    .NET开源作业调度框架Quartz 一 Quartz简介 Quartz是一个强大.开源.轻量的作业调度框架,你能够用它来为执行一个简单或复杂的作业调度任务. 是对非常流行的JAVA开源调度框架 Qu ...

  3. Quartz作业调度框架

    Quartz 是一个开源的作业调度框架,它完全由 Java 写成,并设计用于 J2SE 和 J2EE 应用中.它提供了巨大的灵活性而不牺牲简单性.你能够用它来为执行一个作业而创建简单的或复杂的调度.本 ...

  4. Quartz作业调度框架及时间表达式的含义和语法

    Quartz 是一个开源的作业调度框架,它完全由 Java 写成,并设计用于 J2SE 和 J2EE 应用中.它提供了巨大的灵活性而不牺牲简单性.你能够用它来为执行一个作业而创建简单的或复杂的调度.本 ...

  5. 作业调度框架 Quartz.NET 2.0 StepByStep

    注:目前网上诸多介绍Quartz.net的文章,甚至Quartz.net官网上的Tutorial都是1.0版本的,而这个项目在2.0版本对项目进行了比较大规模的修改,使得原有的很多例子都不能运行,故写 ...

  6. .Net平台开源作业调度框架Quartz.Net

    Quartz.NET介绍: Quartz.NET是一个开源的作业调度框架,是OpenSymphony 的 Quartz API的.NET移植,它用C#写成,可用于winform和asp.net应用中. ...

  7. Quartz - 作业调度框架-插件化开发

    背景 大部分业务都是基于定时的任务,特别适合使用quartz这类框架解决定时问题.具体quartz的使用,看官方文档就可以了.下面谈谈对quartz插件化的封装.我们使用quartz.plugin.然 ...

  8. AngularJS』一点小小的理解

    『AngularJS』一点小小的理解 AngularJS 是一个前端的以Javascript为主的MVC框架.与AngularJS相类似的还有EmberJS. 随着时代在进步,各种各样的开发理念与开发 ...

  9. 作业调度框架_Quartz

    什么是Quartz Quartz是一个完全由Java编写的开源作业调度框架,为在Java应用程序中进行作业调度提供了简单却强大的机制.Quartz允许开发人员根据时间间隔来调度作业.它实现了作业和触发 ...

最新文章

  1. 4、EIGRP配置实验之手动汇总
  2. c语言中小数乘法怎样写程序,四年级下册lbrack;小数乘法rsqb;知识点归纳
  3. 自适应/响应式网页设计
  4. Android开发的之基本控件和详解四种布局方式
  5. hashtable和hashmap的区别?
  6. 关键时刻不可或缺的5款高科技紧急应用
  7. nginx日志查看goaccess安装使用
  8. php转型mysql dba_MySQL_DBA整理(转)
  9. 计算机科学家 收入,你离年薪100万的数据科学家还差10个“码农”
  10. spring boot 视图层(JAVA之学习-2)
  11. BLE MESH中的Secure Network beacon包
  12. 网恋背后的骗局:那些被宰杀掉的猪!必看!
  13. echarts关系图
  14. 解决VS Code 运行 “conda : The term ‘conda‘ is not recognized as the name of a cmdlet, function, script “
  15. 饿了么率先抢占三四线城市,外卖市场新一轮大战在即?
  16. 计算机控制点火系统检修,《发动机电控技术》教学教案:计算机控制点火系统的组成及工作原理...
  17. 08-Hadoop之Zookeeper详解
  18. 【C++进阶】第二十篇——map和set(map和set的用法+multimap+multiset+map和set代码实现)
  19. 【转】我的第一次和最后一次 Hackathon 经历
  20. 工具条(Ext.Toolbar)

热门文章

  1. 急速rust服务器管理_Rust 与服务端编程的碎碎念
  2. python 做山水画_服了!年度最强的编程语言来了!它不是Python!
  3. 【checkStyle】ignore some class
  4. iOS自定义View 控件自动计算size能力
  5. oracle分页数据,oracle 分页 数据重复 数据不正确
  6. delphi listview 获取行高_《我的侠客》布料怎么获得 布料获取方法
  7. 20172310 2017-2018-2 《程序设计与数据结构》第八周学习总结
  8. 软件工程作业No.5
  9. 树莓派(Raspberry Pi 3) centos7使用yum命令报错File /usr/bin/yum, line 30 except KeyboardInterrupt, e:...
  10. lncRNA研究利器之TANRIC