这种不需要强记,需要的时候查下就行,推荐一个工具站吧,Cron校验工具。
测试
感觉我的博客内容好单调,内容框架就是开头,代码,测试,结尾,唉
不过做啥东西,测试少不了,最起码你的东西能用,才说明可行。
我们在Values添加一个方法,这里我们5s一执行(懒得等)。
[HttpGet]
[Route("QuartzTest")]
public void QuartzTest(int type)
{
JobKey jobKey = new JobKey("demo","group1");
switch (type)
{
//添加任务
case 1:
var trigger = TriggerBuilder.Create()
.WithDescription("触发器描述")
.WithIdentity("test")
//.WithSchedule(CronScheduleBuilder.CronSchedule("0 0/30 * * * ? *").WithMisfireHandlingInstructionDoNothing())
.WithSimpleSchedule(x=>x.WithIntervalInSeconds(5).RepeatForever().WithMisfireHandlingInstructionIgnoreMisfires())
.Build();
QuartzUtil.Add(typeof(MyJob), jobKey, trigger);
break;
//暂停任务
case 2:
QuartzUtil.Stop(jobKey);
break;
//恢复任务
case 3:
QuartzUtil.Resume(jobKey);
break;
}
}
让我们来愉快的运行吧,记得appsettings配置个路径访问白名单。
一番1,2,3输入完之后,我们来看下日志。
- 执行任务--- ok
- 暂停任务--- ok
- 恢复任务--- ok
问题及解决方法
但是问题出现了,暂停恢复后,连执行了多次(具体看你间隔时间以及你的频率),这个是有点儿怪异,当时我记得这个问题让我鼓捣了好半天,也是各种查资料查方法,但实际呢这个是Quartz的保护机制,为了防止你的操作是因为不可预知的问题导致的,所以有个重做错过的任务,另外我们的代码中触发器也有这个配置WithMisfireHandlingInstructionIgnoreMisfires。
我们来去掉这个重做机制并测试。
CronTrigger
withMisfireHandlingInstructionDoNothing |
不触发立即执行; 等待下次Cron触发频率到达时刻开始按照Cron频率依次执行 |
withMisfireHandlingInstructionIgnoreMisfires |
以错过的第一 个频率时间立刻开始执行; 重做错过的所有频率周期后; 当下一次触发频率发生时间大于当前时间后,再按照正常的Cron频率依次执行 |
withMisfireHandlingInstructionFireAndProceed |
以当前时间为触发频率立刻触发一次执行; 然后按照Cron频率依次执行 |
SimpleTrigger
withMisfireHandlingInstructionFireNow |
以当前时间为触发频率立即触发执行; 执行至FinalTIme的剩余周期次数;以调度或恢复调度的时刻为基准的周期频率,FinalTime根据剩余次数和当前时间计算得到; 调整后的FinalTime会略大于根据starttime计算的到的FinalTime值 |
withMisfireHandlingInstructionIgnoreMisfires |
以错过的第一个频率时间立刻开始执行; 重做错过的所有频率周期;当下一次触发频率发生时间大于当前时间以后,按照Interval的依次执行剩下的频率; 共执行RepeatCount+1次 |
withMisfireHandlingInstructionNextWithExistingCount |
不触发立即执行; 等待下次触发频率周期时刻,执行至FinalTime的剩余周期次数; 以startTime为基准计算周期频率,并得到FinalTime; 即使中间出现pause,resume以后保持FinalTime时间不变 |
withMisfireHandlingInstructionNowWithExistingCount |
以当前时间为触发频率立即触发执行; 执行至FinalTIme的剩余周期次数; 以调度或恢复调度的时刻为基准的周期频率,FinalTime根据剩余次数和当前时间计算得到; 调整后的FinalTime会略大于根据starttime计算的到的FinalTime值 |
withMisfireHandlingInstructionNextWithRemainingCount |
不触发立即执行; 等待下次触发频率周期时刻,执行至FinalTime的剩余周期次数; 以startTime为基准计算周期频率,并得到FinalTime; 即使中间出现pause,resume以后保持FinalTime时间不变 |
withMisfireHandlingInstructionNowWithRemainingCount |
以当前时间为触发频率立即触发执行; 执行至FinalTIme的剩余周期次数; 以调度或恢复调度的时刻为基准的周期频率,FinalTime根据剩余次数和当前时间计算得到; 调整后的FinalTime会略大于根据starttime计算的到的FinalTime值 |
配置规则介绍参考:https://blog.csdn.net/yangshangwei/article/details/78539433
之前在net framework遇到过一个问题,IIS回收问题,网站在20分钟无请求后就停了,任务也紧跟着停了,当时的解决方法是做个windows服务来定时请求网站保持活跃,当然也可以通过禁止回收来保持网站一直运行。
net core中还没部署运行,如果有相关问题,后续也会补充上来一起交流解决。
小结
定时任务在一个后台系统中一般使用场景还算广泛,主要是sql数据统计,sql/文件备份,定时推送等,具体问题具体分析,net core 3.0都已经问世了,学无止境啊。