在yisha框架的使用中,对定时任务进行了微调。
1、DisallowConcurrentExecution注解的添加
//DisallowConcurrentExecution属性 //防止Quartz.NET同时运行相同的作业 add by hangxing.pang 20201025 [DisallowConcurrentExecution] public class JobExecute : IJob { private AutoJobService autoJobService = new AutoJobService(); private AutoJobLogService autoJobLogService = new AutoJobLogService(); public Task Execute(IJobExecutionContext context) { return Task.Run(async () => { TData obj = new TData(); long jobId = 0; JobDataMap jobData = null; AutoJobEntity dbJobEntity = null; try { jobData = context.JobDetail.JobDataMap; jobId = jobData["Id"].ParseToLong(); // 获取数据库中的任务 dbJobEntity = await autoJobService.GetEntity(jobId); if (dbJobEntity != null) { if (dbJobEntity.JobStatus == StatusEnum.Yes.ParseToInt()) { CronTriggerImpl trigger = context.Trigger as CronTriggerImpl; if (trigger != null) { if (trigger.CronExpressionString != dbJobEntity.CronExpression) { // 更新任务周期 trigger.CronExpressionString = dbJobEntity.CronExpression; await JobScheduler.GetScheduler().RescheduleJob(trigger.Key, trigger); } #region 执行任务 switch (context.JobDetail.Key.Name) { case "数据库备份": obj = await new DatabasesBackupJob().Start(); break; } #endregion } } } } catch (Exception ex) { obj.Message = ex.GetOriginalException().Message; LogHelper.Error(ex); } try { if (dbJobEntity != null) { if (dbJobEntity.JobStatus == StatusEnum.Yes.ParseToInt()) { #region 更新下次运行时间 await autoJobService.SaveForm(new AutoJobEntity { Id = dbJobEntity.Id, NextStartTime = context.NextFireTimeUtc.Value.DateTime.AddHours(8) }); #endregion #region 记录执行状态 await autoJobLogService.SaveForm(new AutoJobLogEntity { JobGroupName = context.JobDetail.Key.Group, JobName = context.JobDetail.Key.Name, LogStatus = obj.Tag, Remark = obj.Message }); #endregion } } } catch (Exception ex) { obj.Message = ex.GetOriginalException().Message; LogHelper.Error(ex); } }); } }
2、项目开启时,避免第一次就执行定时任务
使用yisha定时任务后,发现一个小问题,就是开启程序时,会先执行一遍所有的定时任务,修改如下:
#region 添加任务计划 /// <summary> /// 添加任务计划 /// </summary> /// <returns></returns> private void AddScheduleJob(List<AutoJobEntity> entityList) { try { foreach (AutoJobEntity entity in entityList) { if (entity.StartTime == null) { entity.StartTime = DateTime.Now; } DateTimeOffset starRunTime = DateBuilder.NextGivenSecondDate(entity.StartTime, 1); if (entity.EndTime == null) { entity.EndTime = DateTime.MaxValue.AddDays(-1); } DateTimeOffset endRunTime = DateBuilder.NextGivenSecondDate(entity.EndTime, 1); var scheduler = JobScheduler.GetScheduler(); IJobDetail job = JobBuilder.Create<JobExecute>().WithIdentity(entity.JobName, entity.JobGroupName).Build(); job.JobDataMap.Add("Id", entity.Id); ICronTrigger trigger = (ICronTrigger)TriggerBuilder.Create() .StartAt(starRunTime) .EndAt(endRunTime) .WithIdentity(entity.JobName, entity.JobGroupName) .WithCronSchedule(entity.CronExpression) .Build(); //避免程序启动就任务全部定时任务启动一次 add by hangxing.pang 20201025 ((CronTriggerImpl)trigger).MisfireInstruction = MisfireInstruction.CronTrigger.DoNothing; scheduler.ScheduleJob(job, trigger); scheduler.Start(); } } catch (Exception ex) { LogHelper.Error(ex); } } #endregion