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 { /// /// 调度管理器 /// public class TaskServer : ServiceControl { #region 成员变量 //任务列表 private List _tasks { get; set; } //计划列表 private Dictionary _plans { get; set; } //任务工厂 private ISchedulerFactory _sfactory = new StdSchedulerFactory(); private IScheduler _sched = null; //发布服务宿主 private ServiceHost PublishHost = new ServiceHost(typeof(TaskService)); #endregion /// /// 输出日志委托 /// /// 所属容器 /// sql语句 /// 参数 public delegate void ExportMonitorEventHandler(object sender, MonitorInfo arg); /// /// 输出日志事件 /// public event ExportMonitorEventHandler ExportMonitorEvent = null; #region 属性 //监控信息 public Dictionary MonitorInfos { get; set; } /// /// 运行状态 /// 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; } } /// /// TopShelf's method delegated to . /// 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; } } /// /// TopShelf's method delegated to . /// 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; } } /// /// Pauses all activity in scheduler. /// public virtual void Pause() { //scheduler.PauseAll(); } /// /// Resumes all activity in server. /// public void Resume() { //scheduler.ResumeAll(); } /// /// TopShelf's method delegated to . /// public bool Pause(HostControl hostControl) { Pause(); return true; } /// /// TopShelf's method delegated to . /// public bool Continue(HostControl hostControl) { Resume(); return true; } /// /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// 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 GetTaskList() { List tasks = null; XmlHelper xml = new XmlHelper(Configuration.TaskConfigPath()); tasks = xml.GetData("Task/TaskDetail"); return tasks; } #endregion #region 计划管理 /// /// 载入计划 /// public void LoadPlans() { _plans = new Dictionary(); //获取计划信息 List plans = new PlanInfoManage().GetPlanList(); //初始化监控信息 MonitorInfos = new Dictionary(); //循环添加计划 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(); } /// /// 添加计划 /// /// /// 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; } /// /// 删除计划 /// /// /// 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; } } /// /// 启动计划 /// /// /// 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; } } /// /// 停止计划 /// /// /// 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 状态监控 /// /// 获取监控信息 /// /// public List GetPlanMonitorInfos() { try { List returnMonitors = new List(); //获取监控信息 List monitors = MonitorInfos.Values.ToList(); //获取计划信息 List 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; } } /// /// 输出监控信息 /// /// public void OutputMonitor(MonitorInfo monitor) { if (this.ExportMonitorEvent != null) { this.ExportMonitorEvent(this, monitor); } } #endregion } }