#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;
using Quartz.Impl.Matchers;
namespace WIDESEAWCS_QuartzJob
{
///
/// 调度服务实现类
///
public class SchedulerCenterServer : ISchedulerCenter
{
private IScheduler _scheduler;
private readonly IJobFactory _iocjobFactory;
///
/// 调度服务实现类
///
///
public SchedulerCenterServer(IJobFactory jobFactory)
{
_iocjobFactory = jobFactory;
_scheduler = GetSchedulerAsync();
}
private 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);
StdSchedulerFactory factory = new StdSchedulerFactory();
return _scheduler = factory.GetScheduler().Result;
}
catch (Exception ex)
{
throw new QuartzJobException(string.Format(QuartzJobExceptionMessage.JobFactoryInstanceException, ex.Message), innerException: ex);
}
}
}
///
/// 开启任务调度
///
///
public async Task StartScheduleAsync()
{
WebResponseContent result = new WebResponseContent();
try
{
if (_scheduler.IsShutdown && _scheduler.IsStarted)
{
// 从Factory中获取Scheduler实例
NameValueCollection collection = new NameValueCollection
{
{ "quartz.serializer.type", "binary" },
};
//StdSchedulerFactory factory = new StdSchedulerFactory(collection);
StdSchedulerFactory factory = new StdSchedulerFactory();
_scheduler = factory.GetScheduler().Result;
}
this._scheduler.JobFactory = this._iocjobFactory;
if (!this._scheduler.IsStarted)
{
//等待任务运行完成
await this._scheduler.Start();
await Console.Out.WriteLineAsync(QuartzJobInfoMessage.StartJobSuccess);
result = WebResponseContent.Instance.OK(QuartzJobInfoMessage.StartJobSuccess);
return result;
}
else
{
await _scheduler.Shutdown();
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 (!_scheduler.IsShutdown)
{
//等待任务运行完成
await _scheduler.Shutdown(false);
await Console.Out.WriteLineAsync(QuartzJobInfoMessage.StopJobSuccess);
result = WebResponseContent.Instance.OK(QuartzJobInfoMessage.StopJobSuccess);
return result;
}
else
{
IReadOnlyCollection jobGroupNames = await _scheduler.GetJobGroupNames();
await _scheduler.PauseAll();
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
{
if (_scheduler.IsShutdown && _scheduler.IsStarted)
{
// 从Factory中获取Scheduler实例
NameValueCollection collection = new NameValueCollection
{
{ "quartz.serializer.type", "binary" },
};
//StdSchedulerFactory factory = new StdSchedulerFactory(collection);
StdSchedulerFactory factory = new StdSchedulerFactory();
_scheduler = factory.GetScheduler().Result;
}
JobKey jobKey = new JobKey(tasksQz.Id.ToString(), tasksQz.JobGroup);
if (await _scheduler.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);
}
#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) ?? throw new Exception($"未找到程序集里面该类型,【{tasksQz.AssemblyName}. {tasksQz.ClassName}】");
#endregion
//判断任务调度是否开启
if (!_scheduler.IsStarted)
{
await StartScheduleAsync();
}
//传入反射出来的执行程序集
IJobDetail job = new JobDetailImpl(tasksQz.Id.ToString(), tasksQz.JobGroup, jobType);
job.JobDataMap.Add("JobParams", tasksQz.JobParams);
ITrigger trigger = CreateSimpleTrigger(tasksQz);
// 告诉Quartz使用我们的触发器来安排作业
await _scheduler.ScheduleJob(job, 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.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.CheckExists(jobKey))
{
result = WebResponseContent.Instance.Error(string.Format(QuartzJobInfoMessage.JobNotExist, sysSchedule.Name));
return result;
}
else
{
await this._scheduler.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.CheckExists(jobKey))
{
result = WebResponseContent.Instance.Error(string.Format(QuartzJobInfoMessage.ResumeJobNotExist, sysSchedule.Name));
return result;
}
await this._scheduler.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 PauseAllJobAsync()
//{
// WebResponseContent result = new WebResponseContent();
// if (_scheduler.IsStarted && !_scheduler.IsShutdown)
// {
// await _scheduler.PauseAll();
// }
// return WebResponseContent.Instance.OK();
//}
//public async Task ResumeAllJobAsync()
//{
// WebResponseContent result = new WebResponseContent();
// if (_scheduler.IsStarted && !_scheduler.IsShutdown)
// await _scheduler.ResumeAll();
// return WebResponseContent.Instance.OK();
//}
///
/// 暂停指定的计划任务
///
///
///
public async Task PauseJob(DispatchInfoDTO sysSchedule)
{
WebResponseContent result = new WebResponseContent();
try
{
JobKey jobKey = new JobKey(sysSchedule.Id.ToString(), sysSchedule.JobGroup);
if (!await _scheduler.CheckExists(jobKey))
{
result = WebResponseContent.Instance.Error(string.Format(QuartzJobInfoMessage.PauseJobNotExist, sysSchedule.Name));
return result;
}
await this._scheduler.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.CheckExists(jobKey))
{
//不存在 则 添加一个计划任务
await AddScheduleJobAsync(tasksQz);
//触发执行一次
await _scheduler.TriggerJob(jobKey);
//停止任务
await StopScheduleJobAsync(tasksQz);
result = WebResponseContent.Instance.OK(string.Format(QuartzJobInfoMessage.ExecuteJobSuccess, tasksQz.Name));
}
else
{
await _scheduler.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;
}
}
}