using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Quartz;
using Quartz.Impl;
using Quartz.Impl.Triggers;
using Quartz.Spi;
using WIDESEA_Common;
using WIDESEA_Common.CutomerModel;
using WIDESEA_Core.Utilities;
using WIDESEA_WCS.WCSClient;
namespace WIDESEA_WCS
{
///
/// 任务调度管理中心
///
public class SchedulerCenterServer : ISchedulerCenterServer
{
private Task _scheduler;
private StdSchedulerFactory _jobFactory;
public SchedulerCenterServer(StdSchedulerFactory jobFactory)
{
_jobFactory = jobFactory;
_scheduler = GetSchedulerAsync();
}
private Task GetSchedulerAsync()
{
if (_scheduler != null)
return this._scheduler;
else
{
// 从Factory中获取Scheduler实例
NameValueCollection collection = new NameValueCollection
{
{ "quartz.serializer.type", "binary" },
};
StdSchedulerFactory factory = new StdSchedulerFactory(collection);
return _scheduler = factory.GetScheduler();
}
}
#region 将任务计划添加到调度中心
///
/// 添加一个任务
///
///
///
public async Task AddScheduleJobAsync(JobOptions job)
{
WebResponseContent content = new WebResponseContent();
if (job != null)
{
try
{
JobKey jobKey = new JobKey(job.JobName, job.JobGroup);
if (!await this._scheduler.Result.CheckExists(jobKey))
{
//await Console.Out.WriteLineAsync($"该任务计划已经在执行:【{job.JobName}】,请勿重复启动!");
//content = content.Error($"该任务计划已经在执行:【{job.JobName}】,请勿重复启动!");
//return content;
#region 设置开始时间和结束时间
if (job.BeginTime == null)
{
job.BeginTime = DateTime.Now;
}
DateTimeOffset starRunTime = DateBuilder.NextGivenSecondDate(job.BeginTime, 1);//设置开始时间
if (job.EndTime == null)
{
job.EndTime = DateTime.MaxValue.AddDays(-1);
}
DateTimeOffset endRunTime = DateBuilder.NextGivenSecondDate(job.EndTime, 1);//设置暂停时间
#endregion
Assembly assembly = Assembly.Load(new AssemblyName(job.AssemblyName));
Type jobType = assembly.GetType(job.AssemblyName + "." + job.ClassName);
//判断任务调度是否已经开启
//if (!this._scheduler.Result.IsStarted)
//{
// await StartScheduleAsync();
//}
//传入反射出来的执行程序集
IJobDetail jobDetail = new JobDetailImpl(job.JobName, job.JobGroup, jobType);
jobDetail.JobDataMap.Add("JobParams", job.JobParams);
ITrigger trigger;
if (job.Cron != null && CronExpression.IsValidExpression(job.Cron) && job.TriggerType > 0)
{
trigger = CreateCronTrigger(job);
((CronTriggerImpl)trigger).MisfireInstruction = MisfireInstruction.CronTrigger.DoNothing;
}
else
{
trigger = CreateSimpleTrigger(job);
}
// 告诉Quartz使用我们的触发器来安排作业
await _scheduler.Result.ScheduleJob(jobDetail, trigger);
}
await Console.Out.WriteLineAsync($"【{job.JobName}】任务计划添加成功");
return content = content.OK(message: $"【{job.JobName}】添加成功");
}
catch (Exception ex)
{
Console.Out.WriteLine($"任务计划异常:【{ex.Message}】");
//this._scheduler.Dispose();
this._scheduler = null;
return content = content.Error(message: $"任务计划异常:【{ex.Message}】");
}
}
else
{
await Console.Out.WriteLineAsync($"任务计划不存在:【{job?.JobName}】");
content = content.Error($"任务计划不存在:【{job?.JobName}】");
}
return content;
}
#endregion
#region 检测任务是否存在
///
/// 检测任务是否存在
///
///
///
public async Task IsExistScheduleJobAsync(JobOptions job)
{
JobKey jobKey = new JobKey(job.JobName, job.JobGroup);
if (await _scheduler.Result.CheckExists(jobKey))
{
return true;
}
else
{
return false;
}
}
#endregion
#region 暂停指定的计划任务
///
/// 暂停指定的计划任务
///
///
///
public async Task PauseJob(JobOptions job)
{
WebResponseContent content = new WebResponseContent();
try
{
JobKey jobKey = new JobKey(job.JobName, job.JobGroup);
if (!await _scheduler.Result.CheckExists(jobKey))
{
await Console.Out.WriteLineAsync($"未找到要暂停的任务:【{job.JobName}】");
content = content.Error($"未找到要暂停的任务:【{job.JobName}】");
return content;
}
await this._scheduler.Result.PauseJob(jobKey);
await Console.Out.WriteLineAsync($"【{job.JobName}】任务计划暂停成功");
content = content.OK($"【{job.JobName}】暂停成功");
return content;
}
catch (Exception ex)
{
await Console.Out.WriteLineAsync($"【{job.JobName}】暂停任务异常:【{ex.Message}】");
content = content.Error($"【{job.JobName}】暂停任务异常:【{ex.Message}】");
return content;
}
}
#endregion
#region 恢复一个指定的任务
///
/// 恢复一个指定的任务
///
///
///
public async Task ResumeJob(JobOptions job)
{
WebResponseContent content = new WebResponseContent();
try
{
JobKey jobKey = new JobKey(job.JobName, job.JobGroup);
if (!await _scheduler.Result.CheckExists(jobKey))
{
await Console.Out.WriteLineAsync($"未找到要恢复的任务:【{job.JobName}】");
content = content.Error($"未找到要恢复的任务:【{job.JobName}】");
return content;
}
await this._scheduler.Result.ResumeJob(jobKey);
await Console.Out.WriteLineAsync($"【{job.JobName}】任务计划恢复成功");
content = content.OK($"【{job.JobName}】恢复成功");
return content;
}
catch (Exception ex)
{
await Console.Out.WriteLineAsync($"恢复任务【{job.JobName}】异常:【{ex.Message}】");
content = content.Error($"恢复任务异常:【{ex.Message}】");
return content;
}
}
#endregion
#region 开启任务调度
///
/// 开启任务调度
///
///
public async Task StartScheduleAsync()
{
WebResponseContent content = new WebResponseContent();
try
{
if (!this._scheduler.Result.IsStarted)
{
await this._scheduler.Result.Start();
await Console.Out.WriteLineAsync("任务调度开启!");
content = content.OK(message: $"任务调度开启成功");
}
else
{
await Console.Out.WriteLineAsync($"任务调度已经开启");
content = content.Error($"任务调度已经开启");
}
}
catch (Exception ex)
{
await Console.Out.WriteLineAsync($"任务调度开启异常:{ex.Message}");
content = content.Error($"任务调度开启异常:{ex.Message}");
}
return content;
}
#endregion
#region 停止调度中心任务调度
///
/// 停止调度中心任务调度
///
///
public async Task StopScheduleAsync()
{
WebResponseContent content = new WebResponseContent();
try
{
if (!this._scheduler.Result.IsShutdown)
{
await this._scheduler.Result.Shutdown();
await Console.Out.WriteLineAsync("任务调度停止!");
content = content.OK(message: $"任务调度停止成功");
}
else
{
await Console.Out.WriteLineAsync($"任务调度已经停止");
content = content.Error(message: $"任务调度已经停止");
}
}
catch (Exception ex)
{
await Console.Out.WriteLineAsync($"任务调度停止异常:+{ex.Message}");
content = content.Error(message: $"任务调度停止异常:+{ex.Message}");
}
return content;
}
#endregion
#region 停止一个指定的任务计划
///
/// 停止一个指定的任务计划
///
///
///
public async Task StopScheduleJobAsync(JobOptions job)
{
WebResponseContent content = new WebResponseContent();
try
{
JobKey jobKey = new JobKey(job.JobName, job.JobGroup);
if (!await _scheduler.Result.CheckExists(jobKey))
{
await Console.Out.WriteLineAsync($"未找到要暂停的任务:【{ job.JobName}】");
content = content.Error(message: $"未找到要暂停的任务:【{ job.JobName}】");
}
else
{
await this._scheduler.Result.DeleteJob(jobKey);
await Console.Out.WriteLineAsync($"【{job.JobName}】任务计划暂停成功");
content = content.OK(message: $"【{job.JobName}】暂停成功");
}
}
catch (Exception ex)
{
await Console.Out.WriteLineAsync($"【{job.JobName}】任务计划暂停异常:【{ ex.Message}】");
content = content.Error(message: $"暂停任务异常:【{ ex.Message}】");
}
return content;
}
#endregion
#region 状态状态帮助方法
public async Task> GetTaskStaus(JobOptions jobOptions)
{
var ls = new List();
var noTask = new List{ new TaskInfoDto {
JobId = jobOptions.JobName.ObjToString(),
JobGroup = jobOptions.JobGroup,
TriggerId = "",
TriggerGroup = "",
TriggerStatus = "不存在",
PLCConnetState = jobOptions.PLCConnectState
} };
JobKey jobKey = new JobKey(jobOptions.JobName.ToString(), jobOptions.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,
PLCConnetState = jobOptions.PLCConnectState
});
//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(JobOptions job)
{
if (job.CycleRunTimes > 0)
{
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity(job.JobName, job.JobGroup)
.StartAt(job.BeginTime.Value)
.WithSimpleSchedule(x => x
.WithIntervalInSeconds(job.IntervalSecond)
.WithRepeatCount(job.CycleRunTimes - 1))
.EndAt(job.EndTime.Value)
.Build();
return trigger;
}
else
{
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity(job.JobName, job.JobGroup)
.StartAt(job.BeginTime.Value)
.WithSimpleSchedule(x => x
.WithIntervalInSeconds(job.IntervalSecond)
.RepeatForever()
)
.EndAt(job.EndTime.Value)
.Build();
return trigger;
}
}
///
/// 创建类型Cron的触发器
///
///
///
private ITrigger CreateCronTrigger(JobOptions job)
{
// 作业触发器
return TriggerBuilder.Create()
.WithIdentity(job.JobName, job.JobGroup)
.StartAt(job.BeginTime.Value)//开始时间
.EndAt(job.EndTime.Value)//结束数据
.WithCronSchedule(job.Cron)//指定cron表达式
.ForJob(job.JobName, job.JobGroup)//作业名称
.Build();
}
#endregion
#region 立即执行 一个任务
///
/// 立即执行 一个任务
///
///
///
public async Task ExecuteJobAsync(JobOptions job)
{
WebResponseContent result = new WebResponseContent();
try
{
JobKey jobKey = new JobKey(job.JobName.ToString(), job.JobGroup);
//判断任务是否存在,存在则 触发一次,不存在则先添加一个任务,触发以后再 停止任务
if (!await _scheduler.Result.CheckExists(jobKey))
{
//不存在 则 添加一个计划任务
await AddScheduleJobAsync(job);
//触发执行一次
await _scheduler.Result.TriggerJob(jobKey);
//停止任务
await StopScheduleJobAsync(job);
result.Status = true;
result.Message = $"立即执行计划任务:【{job.JobName}】成功";
}
else
{
await _scheduler.Result.TriggerJob(jobKey);
result.Status = true;
result.Message = $"立即执行计划任务:【{job.JobName}】成功";
}
}
catch (Exception ex)
{
result.Message = $"立即执行计划任务失败:【{ex.Message}】";
}
return result;
}
public void Dispose()
{
throw new NotImplementedException();
}
#endregion
}
}