Quartz定时任务调度简单使用

Quartz是一个开源的作业调度框架,OpenSymphony的开源项目。Quartz.Net 是Quartz的C#移植版本。
特性:
1:支持集群,作业分组,作业远程管理。 
2:自定义精细的时间触发器,使用简单,作业和触发分离。
3:数据库支持,可以寄宿Windows服务,WebSite,winform等。
解释:
Scheduler:作业调度器。
IJob:作业接口,继承并实现Execute, 编写执行的具体作业逻辑。
JobBuilder:根据设置,生成一个详细作业信息(JobDetail)。
TriggerBuilder:根据规则,生产对应的Trigger
Quartz的使用步骤
1、使用Nuget安装quartz
2、创建一个ISchedulerFactory,然后获取 Scheduler
3、启动 Scheduler
4、创建 job 任务
5、创建 trigger 触发器
6、使用触发器规划执行任务
Cron表达式使用技巧(循环周期共5秒,开3秒,关2秒):
0/5 * * * * ? 打开
3/5 * * * * ? 关闭
测试代码:
QuartztJobScheduler类:
using Quartz;
using Quartz.Impl;
using System;
using System.Threading.Tasks;
namespace Service.Quartz
{
    public class QuartztJobScheduler
    {
        private static readonly object objlock = new object();
        private static IScheduler scheduler;
        static QuartztJobScheduler()
        {
            if (scheduler == null)
            {
                lock (objlock)
                {
                    if (scheduler == null)
                    {
                        //创建调度器
                        Task<IScheduler> taskScheduler = StdSchedulerFactory.GetDefaultScheduler();
                        scheduler = taskScheduler.Result;
                    }
                }
            }
        }
        public static async void Start()
        {
            //Cron表达式在线生成:http://www.jsons.cn/quartzcron/
            #region 实例说明
            //简单任务的触发器,可以调度用于重复执行的任务
            //ITrigger trigger = TriggerBuilder.Create()
            //  .WithIdentity("triggerName", "groupName")
            //  .WithSimpleSchedule(t =>
            //    t.WithIntervalInSeconds(5)
            //     .RepeatForever())
            //     .Build();
            //复杂任务触发器--使用cron表达式定制任务调度(强烈推荐)
            //"?"号的用法,“?”可以用在 day of month 和 day of week中,他主要是为了解决如下场景,如:每月的1号的每小时的31分钟,正确的表达式是:* 31 * 1 * ?,而不能是:* 31 * 1 * *,因为这样代表每周的任意一天。
            // 由7段构成:秒 分 时 日 月 星期 年(可选)
            //"-" :表示范围  MON-WED表示星期一到星期三
            //"," :表示列举 MON,WEB表示星期一和星期三
            //"*" :表是“每”,每月,每天,每周,每年等
            //"/" :表示增量:0/15(处于分钟段里面) 每15分钟,在0分以后开始,3/20 每20分钟,从3分钟以后开始
            //"?" :只能出现在日,星期段里面,表示不指定具体的值
            //"L" :只能出现在日,星期段里面,是Last的缩写,一个月的最后一天,一个星期的最后一天(星期六)
            //"W" :表示工作日,距离给定值最近的工作日
            //"#" :表示一个月的第几个星期几,例如:"6#3"表示每个月的第三个星期五(1=SUN...6=FRI,7=SAT)
            //官方实例
            //Expression Meaning
            //0 0 12 * * ? 每天中午12点触发
            //0 15 10 ? * * 每天上午10:15触发
            //0 15 10 * * ? 每天上午10:15触发
            //0 15 10 * * ? * 每天上午10:15触发
            //0 15 10 * * ? 2005 2005年的每天上午10:15触发
            //0 * 14 * * ? 在每天下午2点到下午2:59期间的每1分钟触发
            //0 0/5 14 * * ? 在每天下午2点到下午2:55期间的每5分钟触发
            //0 0/5 14,18 * * ? 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发
            //0 0-5 14 * * ? 在每天下午2点到下午2:05期间的每1分钟触发
            //0 10,44 14 ? 3 WED 每年三月的星期三的下午2:10和2:44触发
            //0 15 10 ? * MON-FRI 周一至周五的上午10:15触发
            //0 15 10 15 * ? 每月15日上午10:15触发
            //0 15 10 L * ? 每月最后一日的上午10:15触发
            //0 15 10 L-2 * ? Fire at 10:15am on the 2nd-to-last last day of every month
            //0 15 10 ? * 6L 每月的最后一个星期五上午10:15触发
            //0 15 10 ? * 6L Fire at 10:15am on the last Friday of every month
            //0 15 10 ? * 6L 2002-2005 2002年至2005年的每月的最后一个星期五上午10:15触发
            //0 15 10 ? * 6#3 每月的第三个星期五上午10:15触发
            //0 0 12 1/5 * ? Fire at 12pm (noon) every 5 days every month, starting on the first day of the month.
            //0 11 11 11 11 ? Fire every November 11th at 11:11am.
            #endregion
            #region 定期更新订单信息
            ////创建作业
            //IJobDetail job_UpDateOrderResult = JobBuilder.Create<Pay_UpDateOrderResultJob>().Build();
            ////创建触发器
            //ITrigger trigger_UpDateOrderResult = TriggerBuilder.Create()
            //    .WithIdentity("UpDateOrderResult_trigger", "UpDateOrderResult_group")
            //    .WithSimpleSchedule(t => t.WithIntervalInSeconds(20).RepeatForever())//每20秒执行一次
            //    .StartNow()
            //    .Build();
            //await scheduler.ScheduleJob(job_UpDateOrderResult, trigger_UpDateOrderResult);
            #endregion
            #region 每日对账及同步结算单
            ////创建作业
            //IJobDetail job_VerifyTrxamtAndStatement = JobBuilder.Create<Pay_VerifyTrxamtAndStatementJob>().Build();
            ////创建触发器
            //ITrigger trigger_job_VerifyTrxamtAndStatement = TriggerBuilder.Create()
            //    .WithIdentity("UpDateOrderResult_trigger", "UpDateOrderResult_group")
            //    .WithSimpleSchedule(t => t.WithIntervalInHours(6).RepeatForever()) //每6小时执行一次
            //    .StartNow()
            //    .Build();
            //await scheduler.ScheduleJob(job_VerifyTrxamtAndStatement, trigger_job_VerifyTrxamtAndStatement);
            //StartJobWithCron<Pay_VerifyTrxamtAndStatementJob>("VerifyTrxamtAndStatement", "0 0 6 * * ?"); //每天凌晨6点执行
            StartJobWithSimple<Pay_VerifyTrxamtAndStatementJob>("VerifyTrxamtAndStatement", t => t.WithIntervalInHours(1).RepeatForever());//每1小时执行一次
            #endregion
            await scheduler.Start();
        }
        /// <summary>
        /// 以Simple开始一个工作
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="name"></param>
        /// <param name="simpleInterval"></param>
        public static void StartJobWithSimple<T>(string name, Action<SimpleScheduleBuilder> simpleInterval) where T : IJob
        {
            IJobDetail job = JobBuilder.Create<T>().WithIdentity(name + "_job", name + "_group").Build();
            ITrigger Simple = TriggerBuilder.Create().StartNow()
                .WithSimpleSchedule(simpleInterval)
                .Build() as ISimpleTrigger;
            scheduler.ScheduleJob(job, Simple);
            scheduler.Start();
        }
        /// <summary>
        /// 以Cron开始一个工作
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="name"></param>
        /// <param name="CronExpression"></param>
        public static void StartJobWithCron<T>(string name, string CronExpression) where T : IJob
        {
            IJobDetail job = JobBuilder.Create<T>().WithIdentity(name + "_job", name + "_group").Build();
            ITrigger CronTrigger = TriggerBuilder.Create().StartNow().WithIdentity(name + "_trigger", name + "_group")
                .WithCronSchedule(CronExpression, w => w.WithMisfireHandlingInstructionDoNothing())
                .Build() as ICronTrigger;
            scheduler.ScheduleJob(job, CronTrigger);
            scheduler.Start();
        }
        /// <summary>
        /// Cron修改频率
        /// </summary>
        /// <param name="job"></param>
        /// <param name="trigger"></param>
        /// <param name="CronExpression"></param>
        public static void ModifyJob(IJobDetail job, ICronTrigger trigger, string CronExpression)
        {
            ICronTrigger _ICronTrigger = trigger;
            _ICronTrigger.CronExpressionString = CronExpression;
            scheduler.RescheduleJob(trigger.Key, _ICronTrigger);
        }
        /// <summary>
        /// Simple修改频率
        /// </summary>
        /// <param name="job"></param>
        /// <param name="trigger"></param>
        /// <param name="SimpleTime"></param>
        public static void ModifyJob(IJobDetail job, ISimpleTrigger trigger, TimeSpan SimpleTime)
        {
            ISimpleTrigger _ISimpleTrigger = trigger;
            _ISimpleTrigger.RepeatInterval = SimpleTime;
            scheduler.RescheduleJob(trigger.Key, _ISimpleTrigger);
        }
    }
}
Pay_UpDateOrderResultJob类:
using Quartz;
using System;
using System.Threading.Tasks;
namespace Service.Quartz
{
    //Quartz定时任务默认都是并发执行的,不会等待上一次任务执行完毕,只要间隔时间到就会执行,。
    [DisallowConcurrentExecution] //不允许并发执行
    public class Pay_UpDateOrderResultJob : IJob
    {
        public Task Execute(IJobExecutionContext context)
        {
            return Task.Run(() =>
            {
                try
                {
                    //Debug.WriteLine("测试");
                }
                catch (Exception e)
                {
                    //
                }
            });
        }
    }
}