#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<IScheduler> _scheduler; 
 | 
        private readonly IJobFactory _iocjobFactory; 
 | 
        public SchedulerCenterServer(IJobFactory jobFactory) 
 | 
        { 
 | 
            _iocjobFactory = jobFactory; 
 | 
            _scheduler = GetSchedulerAsync(); 
 | 
        } 
 | 
        private Task<IScheduler> 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); 
 | 
                } 
 | 
  
 | 
            } 
 | 
        } 
 | 
  
 | 
        /// <summary> 
 | 
        /// 开启任务调度 
 | 
        /// </summary> 
 | 
        /// <returns></returns> 
 | 
        public async Task<WebResponseContent> 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); 
 | 
            } 
 | 
        } 
 | 
  
 | 
        /// <summary> 
 | 
        /// 停止任务调度 
 | 
        /// </summary> 
 | 
        /// <returns></returns> 
 | 
        public async Task<WebResponseContent> 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); 
 | 
            } 
 | 
        } 
 | 
  
 | 
        /// <summary> 
 | 
        /// 添加一个计划任务(映射程序集指定IJob实现类) 
 | 
        /// </summary> 
 | 
        /// <typeparam name="T"></typeparam> 
 | 
        /// <param name="tasksQz"></param> 
 | 
        /// <returns></returns> 
 | 
        public async Task<WebResponseContent> 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; 
 | 
            } 
 | 
        } 
 | 
  
 | 
        /// <summary> 
 | 
        /// 任务是否存在? 
 | 
        /// </summary> 
 | 
        /// <returns></returns> 
 | 
        public async Task<bool> IsExistScheduleJobAsync(DispatchInfoDTO sysSchedule) 
 | 
        { 
 | 
            JobKey jobKey = new JobKey(sysSchedule.Id.ToString(), sysSchedule.JobGroup); 
 | 
            if (await _scheduler.Result.CheckExists(jobKey)) 
 | 
            { 
 | 
                return true; 
 | 
            } 
 | 
            else 
 | 
            { 
 | 
                return false; 
 | 
            } 
 | 
        } 
 | 
  
 | 
        /// <summary> 
 | 
        /// 停止一个指定的计划任务 
 | 
        /// </summary> 
 | 
        /// <returns></returns> 
 | 
        public async Task<WebResponseContent> 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); 
 | 
            } 
 | 
        } 
 | 
  
 | 
        /// <summary> 
 | 
        /// 恢复指定的计划任务 
 | 
        /// </summary> 
 | 
        /// <param name="sysSchedule"></param> 
 | 
        /// <returns></returns> 
 | 
        public async Task<WebResponseContent> 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); 
 | 
            } 
 | 
        } 
 | 
  
 | 
        /// <summary> 
 | 
        /// 暂停指定的计划任务 
 | 
        /// </summary> 
 | 
        /// <param name="sysSchedule"></param> 
 | 
        /// <returns></returns> 
 | 
        public async Task<WebResponseContent> 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<List<DispatchInfoDTO>> GetTaskStaus(DispatchInfoDTO sysSchedule) 
 | 
        //{ 
 | 
  
 | 
        //    var ls = new List<TaskInfoDto>(); 
 | 
        //    var noTask = new List<TaskInfoDto>{ 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 创建触发器帮助方法 
 | 
  
 | 
        /// <summary> 
 | 
        /// 创建SimpleTrigger触发器(简单触发器) 
 | 
        /// </summary> 
 | 
        /// <param name="sysSchedule"></param> 
 | 
        /// <returns></returns> 
 | 
        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 
 | 
  
 | 
        /// <summary> 
 | 
        /// 立即执行 一个任务 执行一次 
 | 
        /// </summary> 
 | 
        /// <param name="tasksQz"></param> 
 | 
        /// <returns></returns> 
 | 
        public async Task<WebResponseContent> 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; 
 | 
        } 
 | 
    } 
 | 
} 
 |