举例场景:有一个喝水提醒的任务,每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秒一次进行执行了。
这里面核心思想就是,如果任务发生了变化,那就删除原来的任务,创建新的任务,而不是在原来任务进行编辑。
川公网安备 51010702003150号
留下您的脚步
最近评论