Quartz 是个开源的作业调度框架.
安装:Install-Package Quartz
官网文档地址:https://www.quartz-scheduler.net/documentation/quartz-3.x/tutorial/using-quartz.html
资源比较多,这里不做介绍。
任务设置有两种方式:SimpleTrigger和CronTrigger,如下:
var trigger = (ISimpleTrigger) TriggerBuilder.Create()
.WithIdentity("trigger1", "group1")
.StartAt(myStartTime) // some Date
.ForJob("job1", "group1") // identify job with name, group strings
var trigger = TriggerBuilder.Create()
.WithIdentity("trigger3", "group1")
.WithCronSchedule("0 0/2 8-17 * * ?")
.ForJob("myJob", "group1")
.Build();
第二种的在线表达式生成工具网址:http://cron.qqe2.com/
在这里写个控制台的Demo来看看定时任务的效果,我们先简单的封装一下任务的启动和停止等,主要代码如下:
public class QuartzHelper { private static QuartzHelper instance = new QuartzHelper(); public static QuartzHelper Instance { get { if (instance == null) { instance = new QuartzHelper(); } return instance; } } private const string JOB_GROUP_NAME = "JOB_GROUP_NAME"; private const string TRIGGER_GROUP_NAME = "TRIGGER_GROUP_NAME"; /// <summary> /// 程序调度 /// </summary> private static IScheduler _scheduler; /// <summary> /// 初始化任务调度对象 /// </summary> private QuartzHelper() { } /// <summary> /// 时间间隔执行任务 /// </summary> /// <typeparam name="T">任务类,必须实现IJob接口</typeparam> /// <param name="seconds">时间间隔(单位:毫秒)</param> public async Task StartJobExecuteInterval<T>(int seconds, string jobName = null, string jobGroupName = null, string triggerName = null, string triggerGroupName = null) where T : IJob { await InitJobs(); //IJobDetail job = JobBuilder.Create<T>().WithIdentity("job1", "group1").Build(); IJobDetail job = JobBuilder.Create<T>().Build(); ITrigger trigger = TriggerBuilder.Create() .StartNow() .WithSimpleSchedule(x => x.WithIntervalInSeconds(seconds).RepeatForever()) .Build(); await _scheduler.ScheduleJob(job, trigger); await _scheduler.Start(); } /// <summary> /// 指定时间执行任务 /// </summary> /// <typeparam name="T">任务类,必须实现IJob接口</typeparam> /// <param name="cronExpression">cron表达式,即指定时间点的表达式</param> public async Task<TriggerState> StartJobExecuteByCron<T>(string cronExpression, string jobName, object para = null, DateTime? startTime = null, DateTime? endTime = null, string jobGroupName = JOB_GROUP_NAME, string triggerName = null, string triggerGroupName = TRIGGER_GROUP_NAME) where T : IJob { await InitJobs(); IJobDetail job = JobBuilder.Create<T>() .WithIdentity(jobName, jobGroupName) .Build(); job.JobDataMap.Put("Runner", para); ITrigger trigger; if (startTime == null && endTime == null) { trigger = TriggerBuilder.Create() .WithIdentity(triggerName ?? jobName, triggerGroupName) .WithCronSchedule(cronExpression) .Build(); } else if (startTime != null && endTime == null) { trigger = TriggerBuilder.Create() .WithIdentity(triggerName ?? jobName, triggerGroupName) .StartAt(CronHelper.DateTime2DateTimeOffset(startTime.Value)) .WithCronSchedule(cronExpression) .Build(); } else if (startTime == null && endTime != null) { trigger = TriggerBuilder.Create() .WithIdentity(triggerName ?? jobName, triggerGroupName) .EndAt(CronHelper.DateTime2DateTimeOffset(endTime.Value)) .WithCronSchedule(cronExpression) .Build(); } else { trigger = TriggerBuilder.Create() .WithIdentity(triggerName ?? jobName, triggerGroupName) .StartAt(CronHelper.DateTime2DateTimeOffset(startTime.Value)) .EndAt(CronHelper.DateTime2DateTimeOffset(endTime.Value)) .WithCronSchedule(cronExpression) .Build(); } await _scheduler.ScheduleJob(job, trigger); await _scheduler.Start(); return await _scheduler.GetTriggerState(trigger.Key); } public async Task<TriggerState> ModifyJobTime(string cronExpression, string jobName, string jobGroupName = JOB_GROUP_NAME, string triggerName = null, string triggerGroupName = TRIGGER_GROUP_NAME) { IJobDetail job; ITrigger trigger; job = await _scheduler.GetJobDetail(new JobKey(jobName, jobGroupName)); trigger = await _scheduler.GetTrigger(new TriggerKey(triggerName ?? jobName, triggerGroupName)); if (job == null || trigger == null) { return TriggerState.None; } await _scheduler.UnscheduleJob(trigger.Key); trigger = TriggerBuilder.Create() .WithIdentity(trigger.Key.Name, trigger.Key.Group) .WithCronSchedule(cronExpression) .Build(); await _scheduler.ScheduleJob(job, trigger); return await _scheduler.GetTriggerState(trigger.Key); } public async Task<TriggerState> RemoveJob(string jobName, string jobGroupName = JOB_GROUP_NAME, string triggerName = null, string triggerGroupName = TRIGGER_GROUP_NAME) { IJobDetail job; ITrigger trigger; job = await _scheduler.GetJobDetail(new JobKey(jobName, jobGroupName)); trigger = await _scheduler.GetTrigger(new TriggerKey(triggerName ?? jobName, triggerGroupName)); if (job == null || trigger == null) { return TriggerState.None; } await _scheduler.UnscheduleJob(trigger.Key); await _scheduler.DeleteJob(job.Key); return await _scheduler.GetTriggerState(trigger.Key); } public async Task<TriggerState> PauseJob(string jobName, string jobGroupName = JOB_GROUP_NAME, string triggerName = null, string triggerGroupName = TRIGGER_GROUP_NAME) { IJobDetail job; ITrigger trigger; job = await _scheduler.GetJobDetail(new JobKey(jobName, jobGroupName)); trigger = await _scheduler.GetTrigger(new TriggerKey(triggerName ?? jobName, triggerGroupName)); if (job == null || trigger == null) { return TriggerState.None; } await _scheduler.PauseJob(job.Key); return await _scheduler.GetTriggerState(trigger.Key); } public async Task<TriggerState> ResumeJob(string jobName, string jobGroupName = JOB_GROUP_NAME, string triggerName = null, string triggerGroupName = TRIGGER_GROUP_NAME) { IJobDetail job; ITrigger trigger; job = await _scheduler.GetJobDetail(new JobKey(jobName, jobGroupName)); trigger = await _scheduler.GetTrigger(new TriggerKey(triggerName ?? jobName, triggerGroupName)); if (job == null || trigger == null) { return TriggerState.None; } await _scheduler.ResumeJob(job.Key); return await _scheduler.GetTriggerState(trigger.Key); } public async Task<TriggerState> GetJobState(string jobName, string jobGroupName = JOB_GROUP_NAME, string triggerName = null, string triggerGroupName = TRIGGER_GROUP_NAME) { IJobDetail job; ITrigger trigger; job = await _scheduler.GetJobDetail(new JobKey(jobName, jobGroupName)); trigger = await _scheduler.GetTrigger(new TriggerKey(triggerName ?? jobName, triggerGroupName)); if (job == null || trigger == null) { return TriggerState.None; } return await _scheduler.GetTriggerState(trigger.Key); } public async Task InitJobs() { if (_scheduler != null) { return; } //配置文件的方式,配置quartz实例 ISchedulerFactory schedulerFactory = new StdSchedulerFactory(); _scheduler = await schedulerFactory.GetScheduler(); } public async Task StartJobs() { if (_scheduler != null) { await _scheduler.Start(); return; } //配置文件的方式,配置quartz实例 ISchedulerFactory schedulerFactory = new StdSchedulerFactory(); _scheduler = await schedulerFactory.GetScheduler(); await _scheduler.Start(); } public void StandbyJobs() { try { if (_scheduler == null) return; if (!_scheduler.InStandbyMode) { _scheduler.Standby(); } } catch (Exception ex) { throw new Exception(ex.Message); } } public void RestartJobs() { _scheduler.Shutdown(); _scheduler.Start(); } public DateTime[] GetNextRunTime(string cronExpression, DateTime? startTime,DateTime? endTime, int number = 1) { try { ITrigger trigger = null; if (startTime == null && endTime == null) { trigger = TriggerBuilder.Create() .WithCronSchedule(cronExpression) .Build(); } else if (startTime != null && endTime == null) { trigger = TriggerBuilder.Create() .StartAt(CronHelper.DateTime2DateTimeOffset(startTime.Value)) .WithCronSchedule(cronExpression) .Build(); } else if (startTime == null && endTime != null) { trigger = TriggerBuilder.Create() .EndAt(CronHelper.DateTime2DateTimeOffset(endTime.Value)) .WithCronSchedule(cronExpression) .Build(); } else { trigger = TriggerBuilder.Create() .StartAt(CronHelper.DateTime2DateTimeOffset(startTime.Value)) .EndAt(CronHelper.DateTime2DateTimeOffset(endTime.Value)) .WithCronSchedule(cronExpression) .Build(); } IList<DateTimeOffset> dates = TriggerUtils.ComputeFireTimes(trigger as IOperableTrigger, null, number).ToList(); if (dates != null && dates.Count > 0) { return dates.Select(p => TimeZoneInfo.ConvertTimeFromUtc(p.DateTime, TimeZoneInfo.Local)).ToArray(); } } catch (Exception ex) { } return null; } }
执行一个每5s执行一次的例子如下:
var TriggerState = await QuartzHelper.Instance.StartJobExecuteByCron<HelloJob>("0/5 * * * * ?", "测试1");