#region << 版 本 注 释 >> /*---------------------------------------------------------------- * 命名空间:WIDESEAWCS_QuartzJob * 创建者:胡童庆 * 创建时间:2024/8/2 16:13:36 * 版本:V1.0.0 * 描述:调度服务实现类 * * ---------------------------------------------------------------- * 修改人: * 修改时间: * 版本:V1.0.1 * 修改说明: * *----------------------------------------------------------------*/ #endregion << 版 本 注 释 >> using Quartz.Impl.Triggers; using Quartz.Impl; using Quartz.Spi; using Quartz; using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; using WIDESEAWCS_Core; using WIDESEAWCS_Core.Helper; using WIDESEAWCS_QuartzJob.DTO; using WIDESEAWCS_QuartzJob.CustomException; namespace WIDESEAWCS_QuartzJob { public class SchedulerCenterServer : ISchedulerCenter { private Task _scheduler; private readonly IJobFactory _iocjobFactory; public SchedulerCenterServer(IJobFactory jobFactory) { _iocjobFactory = jobFactory; _scheduler = GetSchedulerAsync(); } private Task GetSchedulerAsync() { if (_scheduler != null) return this._scheduler; else { try { // 从Factory中获取Scheduler实例 NameValueCollection collection = new NameValueCollection { { "quartz.serializer.type", "binary" }, }; StdSchedulerFactory factory = new StdSchedulerFactory(collection); return _scheduler = factory.GetScheduler(); } catch (Exception ex) { throw new QuartzJobException(string.Format(QuartzJobExceptionMessage.JobFactoryInstanceException, ex.Message), innerException: ex); } } } /// /// 开启任务调度 /// /// public async Task StartScheduleAsync() { WebResponseContent result = new WebResponseContent(); try { this._scheduler.Result.JobFactory = this._iocjobFactory; if (!this._scheduler.Result.IsStarted) { //等待任务运行完成 await this._scheduler.Result.Start(); await Console.Out.WriteLineAsync(QuartzJobInfoMessage.StartJobSuccess); result = WebResponseContent.Instance.OK(QuartzJobInfoMessage.StartJobSuccess); return result; } else { result = WebResponseContent.Instance.Error(QuartzJobInfoMessage.JobHasStart); return result; } } catch (Exception ex) { throw new QuartzJobException(string.Format(QuartzJobExceptionMessage.StartJobException, ex.Message), innerException: ex); } } /// /// 停止任务调度 /// /// public async Task StopScheduleAsync() { WebResponseContent result = new WebResponseContent(); try { if (!this._scheduler.Result.IsShutdown) { //等待任务运行完成 await this._scheduler.Result.Shutdown(); await Console.Out.WriteLineAsync(QuartzJobInfoMessage.StopJobSuccess); result = WebResponseContent.Instance.OK(QuartzJobInfoMessage.StopJobSuccess); return result; } else { result = WebResponseContent.Instance.Error(QuartzJobInfoMessage.JobHasStop); return result; } } catch (Exception ex) { throw new QuartzJobException(string.Format(QuartzJobExceptionMessage.StopJobException, ex.Message), innerException: ex); } } /// /// 添加一个计划任务(映射程序集指定IJob实现类) /// /// /// /// public async Task AddScheduleJobAsync(DispatchInfoDTO tasksQz) { WebResponseContent result = new WebResponseContent(); if (tasksQz != null) { try { JobKey jobKey = new JobKey(tasksQz.Id.ToString(), tasksQz.JobGroup); if (await _scheduler.Result.CheckExists(jobKey)) { result = WebResponseContent.Instance.Error(string.Format(QuartzJobInfoMessage.JobHasAdd, tasksQz.Name)); return result; } #region 设置开始时间和结束时间 if (tasksQz.BeginTime == null) { tasksQz.BeginTime = DateTime.Now; } DateTimeOffset starRunTime = DateBuilder.NextGivenSecondDate(tasksQz.BeginTime, 1);//设置开始时间 if (tasksQz.EndTime == null) { tasksQz.EndTime = DateTime.MaxValue.AddDays(-1); } DateTimeOffset endRunTime = DateBuilder.NextGivenSecondDate(tasksQz.EndTime, 1);//设置暂停时间 #endregion #region 通过反射获取程序集类型和类 var basePath = AppContext.BaseDirectory; var dllFile = Path.Combine(basePath, $"{tasksQz.AssemblyName}.dll"); if (!File.Exists(dllFile)) { var msg = $"{tasksQz.AssemblyName}.dll未找到,请检查数据或文件"; //log.Error(msg); throw new Exception(msg); } Assembly assembly = Assembly.Load(new AssemblyName(tasksQz.AssemblyName)); Type jobType = assembly.GetType(tasksQz.AssemblyName + "." + tasksQz.ClassName); #endregion //传入反射出来的执行程序集 //IJobDetail jobDetail = JobBuilder.Create(jobType) // .WithIdentity(tasksQz.Id.ToString(), tasksQz.JobGroup) // .Build(); //jobDetail.JobDataMap.Add("JobParams", tasksQz.JobParams); IJobDetail job = new JobDetailImpl(tasksQz.Id.ToString(), tasksQz.JobGroup, jobType); job.JobDataMap.Add("JobParams", tasksQz.JobParams); ITrigger trigger = CreateSimpleTrigger(tasksQz); // 告诉Quartz使用我们的触发器来安排作业 await _scheduler.Result.ScheduleJob(job, trigger); //await _scheduler.Result.ScheduleJob(jobDetail, trigger); result = WebResponseContent.Instance.OK(string.Format(QuartzJobInfoMessage.JobAddSuccess, tasksQz.Name)); return result; } catch (Exception ex) { throw new QuartzJobException(string.Format(QuartzJobExceptionMessage.AddJobException, tasksQz.Name, ex.Message), innerException: ex); } } else { result = WebResponseContent.Instance.Error(string.Format(QuartzJobInfoMessage.JobNotExist, tasksQz?.Name)); return result; } } /// /// 任务是否存在? /// /// public async Task IsExistScheduleJobAsync(DispatchInfoDTO sysSchedule) { JobKey jobKey = new JobKey(sysSchedule.Id.ToString(), sysSchedule.JobGroup); if (await _scheduler.Result.CheckExists(jobKey)) { return true; } else { return false; } } /// /// 停止一个指定的计划任务 /// /// public async Task StopScheduleJobAsync(DispatchInfoDTO sysSchedule) { WebResponseContent result = new WebResponseContent(); try { JobKey jobKey = new JobKey(sysSchedule.Id.ToString(), sysSchedule.JobGroup); if (!await _scheduler.Result.CheckExists(jobKey)) { result = WebResponseContent.Instance.Error(string.Format(QuartzJobInfoMessage.JobNotExist, sysSchedule.Name)); return result; } else { await this._scheduler.Result.DeleteJob(jobKey); result = WebResponseContent.Instance.OK(string.Format(QuartzJobInfoMessage.StopAJobSuccess, sysSchedule.Name)); return result; } } catch (Exception ex) { throw new QuartzJobException(string.Format(QuartzJobExceptionMessage.StopAJobException, sysSchedule.Name, ex.Message), innerException: ex); } } /// /// 恢复指定的计划任务 /// /// /// public async Task ResumeJob(DispatchInfoDTO sysSchedule) { WebResponseContent result = new WebResponseContent(); try { JobKey jobKey = new JobKey(sysSchedule.Id.ToString(), sysSchedule.JobGroup); if (!await _scheduler.Result.CheckExists(jobKey)) { result = WebResponseContent.Instance.Error(string.Format(QuartzJobInfoMessage.ResumeJobNotExist, sysSchedule.Name)); return result; } await this._scheduler.Result.ResumeJob(jobKey); result = WebResponseContent.Instance.OK(string.Format(QuartzJobInfoMessage.ResumeJobSuccess, sysSchedule.Name)); return result; } catch (Exception ex) { throw new QuartzJobException(string.Format(QuartzJobExceptionMessage.ResumeJobException, sysSchedule.Name, ex.Message), innerException: ex); } } /// /// 暂停指定的计划任务 /// /// /// public async Task PauseJob(DispatchInfoDTO sysSchedule) { WebResponseContent result = new WebResponseContent(); try { JobKey jobKey = new JobKey(sysSchedule.Id.ToString(), sysSchedule.JobGroup); if (!await _scheduler.Result.CheckExists(jobKey)) { result = WebResponseContent.Instance.Error(string.Format(QuartzJobInfoMessage.PauseJobNotExist, sysSchedule.Name)); return result; } await this._scheduler.Result.PauseJob(jobKey); result = WebResponseContent.Instance.OK(string.Format(QuartzJobInfoMessage.PauseJobSuccess, sysSchedule.Name)); return result; } catch (Exception) { throw; } } #region 状态状态帮助方法 //public async Task> GetTaskStaus(DispatchInfoDTO sysSchedule) //{ // var ls = new List(); // var noTask = new List{ new TaskInfoDto { // jobId = sysSchedule.Id.ObjToString(), // jobGroup = sysSchedule.JobGroup, // triggerId = "", // triggerGroup = "", // triggerStatus = "不存在" // } }; // JobKey jobKey = new JobKey(sysSchedule.Id.ToString(), sysSchedule.JobGroup); // IJobDetail job = await this._scheduler.Result.GetJobDetail(jobKey); // if (job == null) // { // return noTask; // } // //info.Append(string.Format("任务ID:{0}\r\n任务名称:{1}\r\n", job.Key.Name, job.Description)); // var triggers = await this._scheduler.Result.GetTriggersOfJob(jobKey); // if (triggers == null || triggers.Count == 0) // { // return noTask; // } // foreach (var trigger in triggers) // { // var triggerStaus = await this._scheduler.Result.GetTriggerState(trigger.Key); // string state = GetTriggerState(triggerStaus.ObjToString()); // ls.Add(new TaskInfoDto // { // jobId = job.Key.Name, // jobGroup = job.Key.Group, // triggerId = trigger.Key.Name, // triggerGroup = trigger.Key.Group, // triggerStatus = state // }); // //info.Append(string.Format("触发器ID:{0}\r\n触发器名称:{1}\r\n状态:{2}\r\n", item.Key.Name, item.Description, state)); // } // return ls; //} public string GetTriggerState(string key) { string state = null; if (key != null) key = key.ToUpper(); switch (key) { case "1": state = "暂停"; break; case "2": state = "完成"; break; case "3": state = "出错"; break; case "4": state = "阻塞"; break; case "0": state = "正常"; break; case "-1": state = "不存在"; break; case "BLOCKED": state = "阻塞"; break; case "COMPLETE": state = "完成"; break; case "ERROR": state = "出错"; break; case "NONE": state = "不存在"; break; case "NORMAL": state = "正常"; break; case "PAUSED": state = "暂停"; break; } return state; } #endregion #region 创建触发器帮助方法 /// /// 创建SimpleTrigger触发器(简单触发器) /// /// /// private ITrigger CreateSimpleTrigger(DispatchInfoDTO sysSchedule) { ITrigger trigger = TriggerBuilder.Create() .WithIdentity(sysSchedule.Id.ToString(), sysSchedule.JobGroup) .StartAt(sysSchedule.BeginTime.GetValueOrDefault()) .WithSimpleSchedule(x => x .WithIntervalInSeconds(sysSchedule.IntervalSecond) .RepeatForever() ) .EndAt(sysSchedule.EndTime.GetValueOrDefault()) .Build(); return trigger; } #endregion /// /// 立即执行 一个任务 执行一次 /// /// /// public async Task ExecuteJobAsync(DispatchInfoDTO tasksQz) { var result = new WebResponseContent(); try { JobKey jobKey = new JobKey(tasksQz.Id.ToString(), tasksQz.JobGroup); //判断任务是否存在,存在则 触发一次,不存在则先添加一个任务,触发以后再 停止任务 if (!await _scheduler.Result.CheckExists(jobKey)) { //不存在 则 添加一个计划任务 await AddScheduleJobAsync(tasksQz); //触发执行一次 await _scheduler.Result.TriggerJob(jobKey); //停止任务 await StopScheduleJobAsync(tasksQz); result = WebResponseContent.Instance.OK(string.Format(QuartzJobInfoMessage.ExecuteJobSuccess, tasksQz.Name)); } else { await _scheduler.Result.TriggerJob(jobKey); result = WebResponseContent.Instance.OK(string.Format(QuartzJobInfoMessage.ExecuteJobSuccess, tasksQz.Name)); } } catch (Exception ex) { throw new QuartzJobException(string.Format(QuartzJobExceptionMessage.ResumeJobException, tasksQz.Name, ex.Message), innerException: ex); } return result; } } }