举例场景:有一个喝水提醒的任务,每15秒钟提醒一次,后台在任务运行中改成了18秒提醒一次,我们需要更新这个喝水提醒的任务。
解决方案:
除了创建一个喝水提醒的任务之外,再加一个任务管理任务,这个调度任务负责来监听配置,如果检测到配置发生了变化,则更新喝水提醒任务。
1、创建控制台程序。
2、引入Quartz的组件。
3、编写Program.cs,让任务跑起来。
using System; using System.Threading; using Quartz; using Quartz.Impl; namespace QuartzManager { class Program { static void Main(string[] args) { Thread taskThread = new Thread(StartTask); taskThread.Start(); Console.Out.WriteLine(""); Console.Out.WriteLine(""); Console.Out.WriteLine(" ***************************************"); Console.Out.WriteLine(" ** **"); Console.Out.WriteLine(" ** 任务启动成功 **"); Console.Out.WriteLine(" ** **"); Console.Out.WriteLine(" ***************************************"); Console.Out.WriteLine(""); Console.Out.WriteLine(""); Console.WriteLine(" 启动时间:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); Console.Out.WriteLine(""); Console.WriteLine(" 若需退出请输入 exit 按回车退出...\r\n"); string userCommand = string.Empty; while (userCommand != "exit") { if (string.IsNullOrEmpty(userCommand) == false) { Console.WriteLine(" 非退出指令,自动忽略..."); } userCommand = Console.ReadLine(); } } /// <summary> /// Starts the task. /// </summary> private static async void StartTask() { ISchedulerFactory sf = new StdSchedulerFactory(); if (SchedulerUtil._scheduler == null) { SchedulerUtil._scheduler = await sf.GetScheduler(); } await SchedulerUtil._scheduler.Start(); #region 调度任务 //创建任务对象 IJobDetail job1 = JobBuilder.Create<TaskManagerJob>().WithIdentity("job1", "group1").Build(); //创建触发器 ITrigger trigger1 = TriggerBuilder.Create().WithIdentity("trigger1", "group1").StartNow() .WithCronSchedule("0/10 * * * * ?").Build(); #endregion #region 任务 喝水提醒 //创建任务对象 IJobDetail job2 = JobBuilder.Create<TaskDrinkTipsJob>().WithIdentity("job2", "group2").Build(); //创建触发器 ITrigger trigger2 = TriggerBuilder.Create().WithIdentity("trigger2", "group2").StartNow() .WithCronSchedule("0/15 * * * * ?").Build(); #endregion await SchedulerUtil._scheduler.ScheduleJob(job1, trigger1); await SchedulerUtil._scheduler.ScheduleJob(job2, trigger2); } } }
这里我设置了喝水提醒任务15秒钟(0/15 * * * * ?)提醒一次,命名为job2、group2、trigger2,组、任务、触发器都命名为2,调度任务都命名为1。
还有个辅助类:SchedulerUtil.cs,来获取Job的corn时间表达式,以及用静态变量存储了IScheduler对象,方便公共读取。
using System.Threading.Tasks; using Quartz; using Quartz.Impl.Triggers; namespace QuartzManager { public class SchedulerUtil { public static IScheduler _scheduler = null; /// <summary> ///获取CronStr /// </summary> /// <param name="triggername">The triggername.</param> /// <param name="groupname">The groupname.</param> /// <returns></returns> public static async Task<string> GetCornString(string triggername, string groupname) { ITrigger jobKeySet = await _scheduler.GetTrigger(new TriggerKey(triggername, groupname)); CronTriggerImpl cti = (jobKeySet as CronTriggerImpl); return cti?.CronExpressionString ?? ""; } } }
4、编写喝水任务类
using System; using System.Threading.Tasks; using Quartz; namespace QuartzManager { /// <summary> /// 喝水提醒任务 /// </summary> /// <seealso cref="IJob" /> public class TaskDrinkTipsJob : IJob { public virtual Task Execute(IJobExecutionContext context) { return Task.Factory.StartNew(EveryTask); } /// <summary> /// 任务实现 /// </summary> public static void EveryTask() { Console.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss}-该喝水了哦"); } } }
每次都打印出喝水提醒的时间,方便我们看目前用的哪个时间。
5、编写调度任务的代码
using System; using System.Threading.Tasks; using Quartz; namespace QuartzManager { /// <summary> /// 调度任务 /// </summary> /// <seealso cref="IJob" /> public class TaskManagerJob : IJob { public virtual Task Execute(IJobExecutionContext context) { return Task.Factory.StartNew(EveryTask); } private static int actioncount = 0; /// <summary> /// 任务实现 /// </summary> public static async Task EveryTask() { actioncount += 1; Console.WriteLine($"调度任务第{actioncount}次执行"); //任务管理代码 if (actioncount>=5) //模拟服务器在运行中改了配置 比如 从每分钟15秒执行 改成了 每分钟18秒执行 { //读取配置 string servertime = "0/18 * * * * ?";//模拟服务器改成了18秒提醒一次 //首先获取喝水任务的时间设置 string crontime =await SchedulerUtil.GetCornString("trigger2", "group2"); if (crontime!= servertime) { await SchedulerUtil._scheduler.DeleteJob(new JobKey("job2", "group2")); //创建任务对象 IJobDetail job2 = JobBuilder.Create<TaskDrinkTipsJob>().WithIdentity("job2", "group2").Build(); //创建触发器 ITrigger trigger2 = TriggerBuilder.Create().WithIdentity("trigger2", "group2").StartNow() .WithCronSchedule(servertime).Build(); await SchedulerUtil._scheduler.ScheduleJob(job2, trigger2); Console.WriteLine($"调度任务更新了喝水任务"); } } } } }
看结果
第五次调度任务提示了更新,再看喝水提醒的时间,已经是18秒一次进行执行了。
这里面核心思想就是,如果任务发生了变化,那就删除原来的任务,创建新的任务,而不是在原来任务进行编辑。
留下您的脚步
最近评论