天天看点

Quartz.Net实现定时调度学习总结

定时调度可以理解为定时执行某个方法或逻辑代码,Timer也可以实现类似的功能。Quartz就是启动定时任务的框架,直接在项目引用后就可以调用。

准备工作:

项目安装Quartz

代码实现:

1.声明Scheduler(作业调度池)

2.声明JobDetail

3.声明Trigger

4.将JobDetail和Trigger添加到作业调度池中

下面是详细的步骤:

项目引用Quartz,使用NuGet包管理器安装,我安装的Quartz是3.0.7版本(不同的版本,对应的api调用方式不一样2.x和3.x区别挺大),对应的.NETFramework版本要求至少为4.5.2。

Quartz.Net实现定时调度学习总结

代码实现部分:

1.Scheduler 作业调度器

StdSchedulerFactory factory = new StdSchedulerFactory();
IScheduler scheduler = await factory.GetScheduler();
await scheduler.Start();
           

2.JobBuilder 根据设置,生成一个详细作业信息(JobDetail)。(也就是具体要执行的逻辑代码)

IJobDetail jobDetail1 = JobBuilder.Create<JobDemo>().WithIdentity("testjob", "group1").WithDescription("我是testjob").Build();
jobDetail1.JobDataMap.Add("name", "张三");
jobDetail1.JobDataMap.Add("age", "20");
           

3.TriggerBuilder   根据规则,生产对应的Trigger。(时间策略,什么时候执行,执行间隔,执行次数等等)

//程序启动2秒后执行,间隔3秒执行一次,一直执行
ITrigger trigger = TriggerBuilder.Create().WithIdentity("testtrigger", "group1").StartAt(new DateTimeOffset(DateTime.Now.AddSeconds(2)))
                  .WithCronSchedule("0/3 * * * * ?").WithDescription("我是testjob的触发器").Build();
           

4.加入作业调度池中

await scheduler.ScheduleJob(jobDetail1, trigger);
           

完整代码如下:

public async static Task Init()
        {
            try
            {
                Console.WriteLine("初始化scheduler.....");

                //1.Scheduler 作业调度器
                StdSchedulerFactory factory = new StdSchedulerFactory();
                IScheduler scheduler = await factory.GetScheduler();
                await scheduler.Start();

                //2.JobBuilder 根据设置,生成一个详细作业信息(JobDetail)。
                IJobDetail jobDetail1 = JobBuilder.Create<JobDemo>().WithIdentity("testjob", "group1").WithDescription("我是testjob").Build();
                jobDetail1.JobDataMap.Add("name", "张三");
                jobDetail1.JobDataMap.Add("age", "20");


                //3.TriggerBuilder   根据规则,生产对应的Trigger
                //程序启动2秒后执行,间隔3秒执行一次,一直执行
                ITrigger trigger = TriggerBuilder.Create().WithIdentity("testtrigger", "group1").StartAt(new DateTimeOffset(DateTime.Now.AddSeconds(2)))
                  .WithCronSchedule("0/3 * * * * ?").WithDescription("我是testjob的触发器").Build();


                //4.加入作业调度池中
                await scheduler.ScheduleJob(jobDetail1, trigger);


                Console.WriteLine("作业添加完成.....");
            }
            catch (Exception)
            {
                throw;
            }

        }
           

其中自定义逻辑是写在第二步的JobDemo类中,代码如下:

//IJob 作业接口,继承并实现Execute, 编写执行的具体作业逻辑。
    public class JobDemo : IJob
    {
        public async Task Execute(IJobExecutionContext context)
        {
            try
            {
                await Task.Run(() =>
                {
                    Console.WriteLine();

                    JobDataMap map = context.JobDetail.JobDataMap;
                    Console.WriteLine(map.Get("name"));
                    Console.WriteLine(map.Get("age"));
                    Console.WriteLine(DateTime.Now.ToString("r"));

                    Console.WriteLine();
                });
            }
            catch (Exception)
            {
                throw;
            }
        }
    }
           

 以上代码实现的逻辑是程序启动2秒后开始打印在第二步中为jobDetail1添加的参数信息。每隔3秒打印一次,只要程序不停止,就一直执行。

如下所示:

Quartz.Net实现定时调度学习总结

用法的补充和扩展:

在第三步,创建Trigger,是为了控制程序运行的周期,运行次数等等

上面代码示例中使用的是Cron表达式,详细用法参考:https://www.cnblogs.com/sunjie9606/archive/2012/03/15/2397626.html

同时网上也有生成Cron表达式的工具,可以根据选择的时间自动生成表达式:https://cron.qqe2.com/

除了Cron表达式外,还有另外的写法来控制程序运行的周期,比如Simple模式。代码如下:

//程序启动立刻执行,间隔一秒执行一次,一共执行2+1次
ITrigger trigger = TriggerBuilder.Create().WithIdentity("testtrigger", "group1").StartNow()
                    .WithSimpleSchedule(x => x.WithIntervalInSeconds(1).WithRepeatCount(2)).WithDescription("我是testjob的触发器").Build();
           

 这段代码可以替换上面实例中第三部分的代码,实现的逻辑是程序启动后立刻执行任务,每隔一秒钟执行一次,一共重复2次,加上刚开始执行的一次,一共会执行3次。

StartNow(),立即执行作业任务

WithIntervalInSeconds(1),一秒执行一次

WithRepeatCount(2),重复执行两次,这里也可以用RepeatForever(),表示永远执行下去,不限制执行次数。

还有很多其他的api可以通过自行查看,查看方法如下:

Quartz.Net实现定时调度学习总结

关于监听Listener

Quartz的监听器用于当任务调度中所关注事件的发生时,能够及时获取这一事件的通知。类似于任务执行过程中邮件、短信类的提醒。Quartz监听器主要有SchedulerListener、 TriggerListener、JobListener三种,分别表示调度器、触发器、任务对应的监听器。

三者使用方法类似。下面以TriggerListener为例,写一个类说明用法:

MyTriggerListener类:

public class MyTriggerListener : ITriggerListener
    {
        public string Name => "MyTriggerListener";

        public async Task TriggerComplete(ITrigger trigger, IJobExecutionContext context, SchedulerInstruction triggerInstructionCode, CancellationToken cancellationToken = default(CancellationToken))
        {
            await Task.Run(() =>
            {
                Console.WriteLine("job完成时调用");
                Console.WriteLine();

            });
        }

        public async Task TriggerFired(ITrigger trigger, IJobExecutionContext context, CancellationToken cancellationToken = default(CancellationToken))
        {
            await Task.Run(() =>
            {
                Console.WriteLine("job执行时调用");
            });
        }

        public async Task TriggerMisfired(ITrigger trigger, CancellationToken cancellationToken = default(CancellationToken))
        {
            await Task.Run(() =>
            {
                Console.WriteLine("错过触发时调用(例:线程不够用的情况下)");
            });
        }

        public async Task<bool> VetoJobExecution(ITrigger trigger, IJobExecutionContext context, CancellationToken cancellationToken = default(CancellationToken))
        {
            //Trigger触发后,job执行时调用本方法。true即否决,job后面不执行。
            await Task.Run(() =>
            {
                Console.WriteLine("Trigger触发后,job执行时调用本方法。");
            });
            return false;
        }
    }
           

自定义的MyTriggerListener实现后,需要添加监听器到指定的trigger,如图所示:

Quartz.Net实现定时调度学习总结

代码: 

scheduler.ListenerManager.AddTriggerListener(new MyTriggerListener());//添加TriggerListener
           

添加完成后,再次启动项目,可以看到在控制台打印了相关信息:

Quartz.Net实现定时调度学习总结

其他两个监听器用法类似。 

关于监听器可以参考下面链接,虽然是java版本的,但是很多东西是相同的,毕竟.Net的Quartz是由java版本变化而来。

https://www.cnblogs.com/mengrennwpu/p/7191229.html