Net作业调度(三) — Quartz.Net进阶

介绍

前面介绍Quartz.Net的基本用法,但在实际应用中,往往有更多的特性需求,比如记录job执行的执行历史,发邮件等。

阅读目录

  1. Quartz.Net插件
  2. TriggerListener,JobListener
  3. Cron表达式
  4. Quartz.Net线程池
  5. 总结

Quartz.Net插件

     Quartz.net 自身提供了一个插件接口(ISchedulerPlugin)用来增加附加功能,看下官方定义:

  public interface ISchedulerPlugin
    {
        void Initialize(string pluginName, IScheduler sched);
       //关闭调度器
        void Shutdown();
        //插件启动
        void Start();
    }

 继承接口,实现自己的插件。

 public class MyPlugin : ISchedulerPlugin
    {
        public void  Initialize(string pluginName, IScheduler sched)
        {
            Console.WriteLine("实例化");
        }
        public  void Start()
        {
             Console.WriteLine("启动");
        }
        public  void Shutdown()
        {
            Console.WriteLine("关闭");
        }
    }

  主函数里面配置要实现的插件,注释部分,一句话搞定。

static void Main(string[] args)
        {
            var properties = new NameValueCollection();
           //MyPlugin 自定义名称。    "命名空间.类名,程序名称"
            properties["quartz.plugin.MyPlugin.type"] = "QuartzDemo3.MyPlugin,QuartzDemo3"; 

            var schedulerFactory = new StdSchedulerFactory(properties);
            var scheduler = schedulerFactory.GetScheduler();

            var job = JobBuilder.Create<HelloJob>()
                .WithIdentity("myJob", "group1")
                .Build();

            var trigger = TriggerBuilder.Create()
                                .WithIdentity("mytrigger", "group1")
                                .WithCronSchedule("/2 * * ? * *")
                                .Build();

            scheduler.ScheduleJob(job, trigger);
            scheduler.Start();
            Thread.Sleep(6000);
            scheduler.Shutdown(true);
            Console.ReadLine();

        }

运行结果如下:

TriggerListener,JobListener

这2个是对触发器和job本身的行为监听器,这样更好方便跟踪Job的状态及运行情况。  

ITriggerListener是官方定义的接口,这里我们直接继承实现。 

public class MyTriggerListener : ITriggerListener
    {
        private string name;

        public void TriggerComplete(ITrigger trigger, IJobExecutionContext context, SchedulerInstruction triggerInstructionCode)
        {
            Console.WriteLine("job完成时调用");
        }
        public void TriggerFired(ITrigger trigger, IJobExecutionContext context)
        {
            Console.WriteLine("job执行时调用");
        }
        public void TriggerMisfired(ITrigger trigger)
        {
            Console.WriteLine("错过触发时调用(例:线程不够用的情况下)");
        }
        public bool VetoJobExecution(ITrigger trigger, IJobExecutionContext context)
        {
            //Trigger触发后,job执行时调用本方法。true即否决,job后面不执行。
            return false;
        }
        public string Name { get { return name; } set { name = value; } }
    }

主函数添加:

           //添加监听器到指定的trigger
            scheduler.ListenerManager.AddTriggerListener(myJobListener, KeyMatcher<TriggerKey>.KeyEquals(new TriggerKey("mytrigger", "group1")));

            ////添加监听器到指定分类的所有监听器。
            //scheduler.ListenerManager.AddTriggerListener(myJobListener, GroupMatcher<TriggerKey>.GroupEquals("myJobGroup"));

            ////添加监听器到指定分类的所有监听器。
            //scheduler.ListenerManager.AddTriggerListener(myJobListener, GroupMatcher<TriggerKey>.GroupEquals("myJobGroup"));

           ////添加监听器到指定的2个分组。
            //scheduler.ListenerManager.AddTriggerListener(myJobListener, GroupMatcher<TriggerKey>.GroupEquals("myJobGroup"), GroupMatcher<TriggerKey>.GroupEquals("myJobGroup2"));

            ////添加监听器到所有的触发器上。
            //scheduler.ListenerManager.AddTriggerListener(myJobListener, GroupMatcher<TriggerKey>.AnyGroup());

            scheduler.Start();

JobListener同理,这里不多做描述。

Cron表达式

quartz中的cron表达式和Linux下的很类似,比如 "/5 * * ? * * *"  这样的7位表达式,最后一位年非必选。

表达式从左到右,依此是秒、分、时、月第几天、月、周几、年。下面表格是要遵守的规范:

字段名

允许的值

允许的特殊字符

Seconds

0-59

, - * /

Minutes

0-59

, - * /

Hours

0-23

, - * /

Day of month

1-31

, - * ? / L W

Month

1-12 or JAN-DEC

, - * /

Day of week

1-7 or SUN-SAT

, - * ? / L #

Year

空, 1970-2099

, - * /

特殊字符

解释

,

或的意思。例:分钟位 5,10  即第5分钟或10分都触发。

/

a/b。 a:代表起始时间,b频率时间。 例; 分钟位  3/5,  从第三分钟开始,每5分钟执行一次。

*

频率。 即每一次波动。    例;分钟位 *  即表示每分钟

-

区间。  例: 分钟位   5-10 即5到10分期间。

?

任意值 。   即每一次波动。只能用在DayofMonth和DayofWeek,二者冲突。指定一个另一个一个要用?

L

表示最后。 只能用在DayofMonth和DayofWeek,4L即最后一个星期三

W

工作日。  表示最后。 只能用在DayofWeek

#

4#2。 只能用DayofMonth。 某月的第二个星期三

实例介绍

”0 0 10,14,16 * * ?"    每天10点,14点,16点 触发。

"0 0/5 14,18 * * ?"    每天14点或18点中,每5分钟触发 。

"0 4/15 14-18 * * ?"       每天14点到18点期间,  从第四分钟触发,每15分钟一次。

"0 15 10 ? * 6L"        每月的最后一个星期五上午10:15触发。

Quartz.Net线程池

线程池数量设置:

properties["quartz.threadPool.threadCount"] = "5";  

这个线程池的设置,是指同时间,调度器能执行Job的最大数量。

quartz是用每个线程跑一个job。上面的设置可以解释是job并发时能执行5个job,剩下的job如果触发时间恰好到了,当前job会进入暂停状态,直到有可用的线程。

如果在指定的时间范围依旧没有可用线程,会触发misfired时间。

quartz 提供了IThreadPool接口,也可以用自定义线程池来实现。

配置如下:

properties["quartz.threadPool.type"] = "Quartz.Simpl.SimpleThreadPool, Quartz"; 

一般来说作业调度很少并发触发大量job,如果有上百个JOB,可在服务器承受范围内适量增加线程数量。     

总结

官方有LoggingTriggerHistoryPlugin,LoggingJobHistoryPlugin  已实现的,触发器和job历史记录的插件。

Quartz.Plugin 命名空间下有官方实现的其他一些插件,也可以自己增加扩展。

quartz中监听器还有SchedulerListener,使用方法基本一样。 

本文基于自用经验和官方文档代码来写的,部分是直接翻译的。 

Quartz.Net官方教程http://www.quartz-scheduler.net/documentation/quartz-2.x/tutorial/index.html

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏晓晨的专栏

Entity Framework Core 2.0 使用代码进行自动迁移

18030
来自专栏Java帮帮-微信公众号-技术文章全总结

Hibernate_day04总结

更多资源分享就在【Java帮帮】微信公众号与QQ空间 Hibernate_day04总结 今日内容 l Hibernate的二级缓存 1.1 上次课内容回顾: ...

29780
来自专栏企鹅号快讯

WebApi client 的面向切面编程

.Net的面向切面编程 .Net的服务端应用AOP很常见,在Asp.net MVC与Asp.net WebApi等新框架里到处都有AOP的影子,我们可以把一个服...

206110
来自专栏.NET开发者社区

基于ASP.NET MVC(C#)和Quartz.Net组件实现的定时执行任务调度

在之前的文章《推荐一个简单、轻量、功能非常强大的C#/ASP.NET定时任务执行管理器组件–FluentScheduler》和《简单、轻量、功能非常强大的C#/...

657100
来自专栏ZKEASOFT

纸壳CMS的插件加载机制

纸壳CMS是基于插件化设计的,可以通过扩展插件来实现不同的功能。如何通过插件来扩展,可以参考这篇文章:

13820
来自专栏菩提树下的杨过

.net中的认证(authentication)与授权(authorization)

注:这篇文章主要给新手看的,老手们可能会觉得没啥营养,就请绕过吧。 “认证”与“授权”是几乎所有系统中都会涉及的概念,通俗点讲: 认证(authenticat...

381100
来自专栏跟着阿笨一起玩NET

C#.Net前台线程与后台线程的区别

 if (!this.IsDisposed ) 也是可以的。判断当前窗体是否已经释放。(备注:释放的窗体是不能操作界面UI元素的。)

35910
来自专栏更流畅、简洁的软件开发方式

一个保存数据的方法(可以切换存放的位置,可以设置密钥)

      在asp.net里面一般的生命周期都比较短,如果想要比较长久的保存数据的话,一般有选择几种方式可供选择,即cookies、ViewState、Ses...

290100
来自专栏蘑菇先生的技术笔记

Net作业调度(二) -CrystalQuartz远程管理

37740
来自专栏菩提树下的杨过

img标签的src=""会引起的Page_Load多次执行

今天看见园子里有人因img的src为空导致session丢失,详情见http://www.cnblogs.com/kyneblog/archive/2009/0...

234100

扫码关注云+社区

领取腾讯云代金券