天津投入产出系统后端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

699 lines
21 KiB

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.ServiceModel;
using Topshelf;
using Quartz;
using Quartz.Impl;
using System.Threading;
namespace QMTask.Core
{
/// <summary>
/// 调度管理器
/// </summary>
public class TaskServer : ServiceControl
{
#region 成员变量
//任务列表
private List<TaskInfo> _tasks { get; set; }
//计划列表
private Dictionary<JobKey, PlanInfo> _plans { get; set; }
//任务工厂
private ISchedulerFactory _sfactory = new StdSchedulerFactory();
private IScheduler _sched = null;
//发布服务宿主
private ServiceHost PublishHost = new ServiceHost(typeof(TaskService));
#endregion
/// <summary>
/// 输出日志委托
/// </summary>
/// <param name="sender">所属容器</param>
/// <param name="sql">sql语句</param>
/// <param name="parameters">参数</param>
public delegate void ExportMonitorEventHandler(object sender, MonitorInfo arg);
/// <summary>
/// 输出日志事件
/// </summary>
public event ExportMonitorEventHandler ExportMonitorEvent = null;
#region 属性
//监控信息
public Dictionary<JobKey, MonitorInfo> MonitorInfos { get; set; }
/// <summary>
/// 运行状态
/// </summary>
public bool Running { get; set; }
#endregion
#region 服务控制
public bool StartService()
{
try
{
//启动远程服务
if (PublishHost.State != CommunicationState.Opening)
PublishHost.Open();
//启动任务调度服务
Start();
Console.WriteLine("已启动");
QMFrameWork.Log.LogManager.LogHelper.Info(
new QMFrameWork.Log.LogInfo { ClientIP = "localhost", UserName = "admin", Info = "服务已启动" });
return true;
}
catch (Exception ex)
{
QMFrameWork.Log.LogManager.LogHelper.Error(
new QMFrameWork.Log.LogInfo { ClientIP = "localhost", UserName = "admin", Info = "启动服务", ErrorInfo = ex });
throw;
}
}
/// <summary>
/// TopShelf's method delegated to <see cref="Start()"/>.
/// </summary>
public bool Start(HostControl hostControl)
{
try
{
//启动远程服务
if (PublishHost.State != CommunicationState.Opening)
PublishHost.Open();
//启动任务调度服务
Start();
Console.WriteLine("已启动");
QMFrameWork.Log.LogManager.LogHelper.Info(
new QMFrameWork.Log.LogInfo { ClientIP = "localhost", UserName = "admin", Info = "服务已启动" });
return true;
}
catch (Exception ex)
{
QMFrameWork.Log.LogManager.LogHelper.Error(
new QMFrameWork.Log.LogInfo { ClientIP = "localhost", UserName = "admin", Info = "启动服务", ErrorInfo = ex });
throw;
}
}
public bool StopService()
{
try
{
//停止远程服务
if (PublishHost.State != CommunicationState.Opening)
PublishHost.Close();
//停止任务调度服务
Stop();
Console.WriteLine("已停止");
QMFrameWork.Log.LogManager.LogHelper.Info(
new QMFrameWork.Log.LogInfo { ClientIP = "localhost", UserName = "admin", Info = "服务已停止" });
return true;
}
catch (Exception ex)
{
QMFrameWork.Log.LogManager.LogHelper.Error(
new QMFrameWork.Log.LogInfo { ClientIP = "localhost", UserName = "admin", Info = "停止服务", ErrorInfo = ex });
throw;
}
}
/// <summary>
/// TopShelf's method delegated to <see cref="Stop()"/>.
/// </summary>
public bool Stop(HostControl hostControl)
{
try
{
//停止远程服务
if (PublishHost.State != CommunicationState.Opening)
PublishHost.Close();
//停止任务调度服务
Stop();
Console.WriteLine("已停止");
QMFrameWork.Log.LogManager.LogHelper.Info(
new QMFrameWork.Log.LogInfo { ClientIP = "localhost", UserName = "admin", Info = "服务已停止" });
return true;
}
catch (Exception ex)
{
QMFrameWork.Log.LogManager.LogHelper.Error(
new QMFrameWork.Log.LogInfo { ClientIP = "localhost", UserName = "admin", Info = "停止服务", ErrorInfo = ex });
throw;
}
}
/// <summary>
/// Pauses all activity in scheduler.
/// </summary>
public virtual void Pause()
{
//scheduler.PauseAll();
}
/// <summary>
/// Resumes all activity in server.
/// </summary>
public void Resume()
{
//scheduler.ResumeAll();
}
/// <summary>
/// TopShelf's method delegated to <see cref="Pause()"/>.
/// </summary>
public bool Pause(HostControl hostControl)
{
Pause();
return true;
}
/// <summary>
/// TopShelf's method delegated to <see cref="Resume()"/>.
/// </summary>
public bool Continue(HostControl hostControl)
{
Resume();
return true;
}
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public virtual void Dispose()
{
// no-op for now
}
#endregion
#region 启动
public void Start()
{
_sched = _sfactory.GetScheduler();
//添加监听
JobListener listener = new JobListener();
listener.MyTaskServer = this;
listener.Name = "listener1";
_sched.ListenerManager.AddJobListener(listener);
//加载任务
this.LoadTasks();
//加载计划
this.LoadPlans();
//启动
_sched.Start();
Running = true;
}
#endregion
#region 停止
public void Stop()
{
_sched.Shutdown(false);
Running = false;
}
#endregion
#region 加载任务
public void LoadTasks()
{
_tasks = this.GetTaskList();
}
#endregion
#region 获取任务列表
public List<TaskInfo> GetTaskList()
{
List<TaskInfo> tasks = null;
XmlHelper xml = new XmlHelper(Configuration.TaskConfigPath());
tasks = xml.GetData<TaskInfo>("Task/TaskDetail");
return tasks;
}
#endregion
#region 计划管理
/// <summary>
/// 载入计划
/// </summary>
public void LoadPlans()
{
_plans = new Dictionary<JobKey, PlanInfo>();
//获取计划信息
List<PlanInfo> plans = new PlanInfoManage().GetPlanList();
//初始化监控信息
MonitorInfos = new Dictionary<JobKey, MonitorInfo>();
//循环添加计划
foreach (PlanInfo plan in plans)
{
if (plan.IsUse == "false")
continue;
IJobDetail job = null;
ICronTrigger trigger=null;
TaskInfo task = null;
this.GetJobAndTrigger(plan, out job, out trigger, out task);
if (task == null)
continue;
_plans.Add(job.Key, plan);
//添加监控信息
MonitorInfo monitor = new MonitorInfo();
monitor.PlanID = plan.PlanID;
monitor.PlanName = plan.PlanName;
monitor.TaskID = task.TaskID;
monitor.TaskName = task.TaskName;
monitor.IsUse = bool.Parse(plan.IsUse);
monitor.IsNormal = true;
MonitorInfos.Add(job.Key,monitor);
//添加触发器
_sched.ScheduleJob(job, trigger);
monitor.Running = true;
}
}
//获取作业与触发器
private void GetJobAndTrigger(PlanInfo plan, out IJobDetail job, out ICronTrigger trigger, out TaskInfo task)
{
//创建触发器表达式
CronExpression ce = new CronExpression();
ce.Build(plan);
//查找对应任务
task = _tasks.Find(p => p.TaskID == plan.TaskID);
if (task == null)
{
job = null;
trigger = null;
return;
}
//创建计划
string rootPath = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
Assembly Asse = Assembly.LoadFile(rootPath + @"\" + task.AssemblyFile);
Type taskType = Asse.GetType(task.TaskType);
job = JobBuilder.Create(taskType).WithIdentity(plan.PlanID, "group1").Build();
//创建触发器
TriggerBuilder tb = TriggerBuilder.Create()
.WithIdentity("tr" + plan.PlanID, "group1")
.WithCronSchedule(ce.ToString());
//设置计划开始日期
if (plan.PlanStartDate != new DateTime())
{
tb = tb.StartAt(DateTimeOffset.Parse(plan.PlanStartDate.ToString("yyyy-MM-dd")));
}
//设置计划结束日期
if (plan.PlanEndDate != new DateTime())
{
tb = tb.EndAt(DateTimeOffset.Parse(plan.PlanEndDate.ToString("yyyy-MM-dd")));
}
trigger = (ICronTrigger)tb.Build();
}
/// <summary>
/// 添加计划
/// </summary>
/// <param name="plan"></param>
/// <returns></returns>
public bool AddPlan(PlanInfo plan)
{
try
{
if (Running == false)
return true;
IJobDetail job = null;
ICronTrigger trigger = null;
TaskInfo task = null;
if (plan.IsUse == "false")
return true;
this.GetJobAndTrigger(plan, out job, out trigger, out task);
if (task == null)
return true;
_plans.Add(job.Key, plan);
//添加监控信息
MonitorInfo monitor = new MonitorInfo();
monitor.PlanID = plan.PlanID;
monitor.PlanName = plan.PlanName;
monitor.TaskID = task.TaskID;
monitor.TaskName = task.TaskName;
MonitorInfos.Add(job.Key, monitor);
//添加触发器
_sched.ScheduleJob(job, trigger);
return true;
}
catch (Exception ex)
{
QMFrameWork.Log.LogManager.LogHelper.Error(
new QMFrameWork.Log.LogInfo { ClientIP = "localhost", UserName = "admin", Info = "添加计划", ErrorInfo = ex });
throw;
}
}
//更新计划
public bool UpdatePlan(PlanInfo plan)
{
bool r;
r=this.DeletePlan(plan);
if (r == false)
{
return r;
}
r=this.AddPlan(plan);
return r;
}
/// <summary>
/// 删除计划
/// </summary>
/// <param name="plan"></param>
/// <returns></returns>
public bool DeletePlan(PlanInfo plan)
{
try
{
if (Running == false)
return false;
JobKey key = null;
PlanInfo updatePlan = null;
updatePlan = this.GetPlanInfo(plan.PlanID, out key);
if (key == null)
{
return true;
}
MonitorInfo monitor = this.GetMonitorInfo(key);
if (monitor.Running == false)
{
_sched.ResumeJob(key);
_sched.DeleteJob(key);
_plans.Remove(key);
MonitorInfos.Remove(key);
}
return true;
}
catch (Exception ex)
{
QMFrameWork.Log.LogManager.LogHelper.Error(
new QMFrameWork.Log.LogInfo { ClientIP = "localhost", UserName = "admin", Info = "删除计划", ErrorInfo = ex });
throw;
}
}
/// <summary>
/// 启动计划
/// </summary>
/// <param name="plan"></param>
/// <returns></returns>
public bool StartPlan(PlanInfo plan)
{
try
{
if (Running == false)
return false;
IJobDetail job = null;
ICronTrigger trigger = null;
TaskInfo task = null;
JobKey key = null;
PlanInfo startPlan = null;
startPlan = this.GetPlanInfo(plan.PlanID, out key);
if (startPlan != null)
return true;
this.GetJobAndTrigger(plan, out job, out trigger, out task);
if (task == null)
return true;
_plans.Add(job.Key, plan);
//添加监控信息
MonitorInfo monitor = new MonitorInfo();
monitor.PlanID = plan.PlanID;
monitor.PlanName = plan.PlanName;
monitor.TaskID = task.TaskID;
monitor.TaskName = task.TaskName;
MonitorInfos.Add(job.Key, monitor);
//添加触发器
_sched.ScheduleJob(job, trigger);
return true;
}
catch (Exception ex)
{
QMFrameWork.Log.LogManager.LogHelper.Error(
new QMFrameWork.Log.LogInfo { ClientIP = "localhost", UserName = "admin", Info = "启动计划", ErrorInfo = ex });
throw;
}
}
/// <summary>
/// 停止计划
/// </summary>
/// <param name="plan"></param>
/// <returns></returns>
public bool StopPlan(PlanInfo plan)
{
try
{
if (Running == false)
return false;
JobKey key = null;
PlanInfo stopPlan = null;
stopPlan = this.GetPlanInfo(plan.PlanID, out key);
if (stopPlan == null)
return true;
stopPlan.IsUse = "false";
MonitorInfo monitor = this.GetMonitorInfo(key);
if (monitor.Running == false)
{
_sched.ResumeJob(key);
_sched.DeleteJob(key);
_plans.Remove(key);
MonitorInfos.Remove(key);
return true;
}
else
{
return false;
}
}
catch (Exception ex)
{
QMFrameWork.Log.LogManager.LogHelper.Error(
new QMFrameWork.Log.LogInfo { ClientIP = "localhost", UserName = "admin", Info = "停止计划", ErrorInfo = ex });
throw;
}
}
private PlanInfo GetPlanInfo(string planID,out JobKey key)
{
PlanInfo plan = null;
key = null;
foreach (JobKey jobkey in _plans.Keys)
{
if (_plans[jobkey].PlanID == planID)
{
plan = _plans[jobkey];
key = jobkey;
break;
}
}
return plan;
}
private MonitorInfo GetMonitorInfo(JobKey key)
{
if (MonitorInfos.ContainsKey(key) == true)
{
return MonitorInfos[key];
}
else
{
return null;
}
}
#endregion
#region 状态监控
/// <summary>
/// 获取监控信息
/// </summary>
/// <returns></returns>
public List<MonitorInfo> GetPlanMonitorInfos()
{
try
{
List<MonitorInfo> returnMonitors = new List<MonitorInfo>();
//获取监控信息
List<MonitorInfo> monitors = MonitorInfos.Values.ToList();
//获取计划信息
List<PlanInfo> plans = new PlanInfoManage().GetPlanList();
//关联
foreach (PlanInfo plan in plans)
{
MonitorInfo monitor = null;
TaskInfo task = _tasks.Find(p => p.TaskID == plan.TaskID);
monitor = monitors.Find(p => p.PlanID == plan.PlanID);
if (monitor == null)
{
monitor = new MonitorInfo();
monitor.Running = false;
monitor.IsUse = false;
}
monitor.PlanID = plan.PlanID;
monitor.PlanName = plan.PlanName;
monitor.TaskID = plan.TaskID;
monitor.TaskName = task.TaskName;
string intervalType = "";
string periodType = "";
switch (plan.IntervalType)
{
case "s":
intervalType = "秒";
break;
case "m":
intervalType = "分";
break;
case "h":
intervalType = "小时";
break;
}
switch (plan.PeriodType)
{
case "d":
if (string.IsNullOrEmpty(plan.OnceTime) == false)
{
periodType = "每天";
}
else
{
periodType = "每" + plan.Interval + intervalType;
}
break;
case "w":
periodType = "每周";
break;
case "m":
if (plan.Period == 1)
{
periodType = "每月";
}
else
{
periodType = "每" + plan.Period.ToString() + "月";
}
break;
}
monitor.ExecuteInterval = periodType;
monitor.Remark = plan.Remark;
returnMonitors.Add(monitor);
}
return returnMonitors;
}
catch (Exception ex)
{
QMFrameWork.Log.LogManager.LogHelper.Error(
new QMFrameWork.Log.LogInfo { ClientIP = "localhost", UserName = "admin", Info = "获取监控信息", ErrorInfo = ex });
throw ex;
}
}
/// <summary>
/// 输出监控信息
/// </summary>
/// <param name="monitor"></param>
public void OutputMonitor(MonitorInfo monitor)
{
if (this.ExportMonitorEvent != null)
{
this.ExportMonitorEvent(this, monitor);
}
}
#endregion
}
}