该框架设计主要用于后台执行任务,只须要动态的去添加执行任务便可,而不须要关心任务开始、中止以及任务状态信息等。旨在更加方便的去管理多个任务。数据库
任务集框架设置图以下,主要分为4大模块,config、log、help、task 这四个模块。json
Config 模块主要是各个任务的配置文件。框架
Log模块主要是记录各个任务产生的日志文件。ide
Helper模块主要是全部的任务须要用到的工具集。工具
Tasks 模块主要是各个任务的集合设计
该模块主要用于任务框架开启中止的入口,同时配置界面,能够在框架运行过程当中手动日志
开启,中止任务以及配置任务。经过界面展现,能够详细的看到任务的执行次数,错误次数以及任务的当前状态。界面以下:code
任务状态:表示任务当前的执行状态。表示当前任务未开启,表示当前任务已暂停,表示当前任务正在运行中。xml
任务次数:表示当前任务总共执行的次数。blog
错误次数:表示当前任务总共执行的错误次数
任务周期:表示当前任务执行了多少个任务周期,一个周期是86400个任务次数。
该模块用于全部的任务的配置。
示例以下:
<?xml version="1.0" encoding="utf-8" ?>
<root>
<dataenginerpath>C:\Users\lining\Documents\Visual Studio 2015\Projects1\EcgNetPlug\bin\x86\Debug\config\FetalDataEnginer\release\testpro.exe</dataenginerpath>
<dataenginername>testPro</dataenginername>
<!--休眠时间-->
<sleeptime>10000</sleeptime>
</root>
该模块用于记录全部的任务在运行期间的日志数据。该模块使用Log4Net,一个开源的
日志库。感受仍是挺好用的。几乎能想到的功能都有。
日志示例以下:
2017-07-24 08:47:56,382 FetalDataEnginerWorkJob [8] ERROR Process.Kill:拒绝访问。
2017-07-24 08:48:08,891 FetalDataEnginerWorkJob [8] ERROR Process.Kill:拒绝访问。
2017-07-24 08:58:01,891 FetalDataEnginerWorkJob [9] ERROR Process.Kill:拒绝访问。
2017-07-24 08:58:12,431 FetalDataEnginerWorkJob [9] ERROR Process.Kill:拒绝访问。
2017-07-24 09:00:08,782 FetalDataEnginerWorkJob [10] ERROR Process.Kill:拒绝访问。
2017-07-24 09:04:39,821 FetalDataEnginerWorkJob [9] ERROR Process.Kill:拒绝访问。
2017-07-24 10:22:19,719 FetalDataEnginerWorkJob [10] ERROR Process.Kill:拒绝访问。
2017-07-24 10:24:03,266 FetalDataEnginerWorkJob [1] ERROR Process.Kill:拒绝访问。
2017-07-24 10:25:33,186 FetalDataEnginerWorkJob [1] ERROR Process.Kill:拒绝访问。
2017-07-24 10:30:00,554 FetalDataEnginerWorkJob [1] ERROR Process.Kill:拒绝访问。
2017-07-24 10:43:53,695 FetalDataEnginerWorkJob [1] ERROR Process.Kill:拒绝访问。
2017-07-24 14:43:51,249 FetalDataEnginerWorkJob [10] ERROR Process.Kill:拒绝访问。
2017-07-24 16:17:50,396 FetalDataEnginerWorkJob [9] ERROR Process.Kill:拒绝访问。
2017-07-24 16:18:07,162 FetalDataEnginerWorkJob [10] ERROR Process.Kill:拒绝访问。
该模块主要是一些工具的集合,该项目中目前存放一些数据库的操做类,以及XML 文
档的操做类等。
该模块是全部的任务执行实体,每一个任务继承BaseJob,而后实现里面的Start Stop 和
Run 方法。BaseJob 会在每秒钟会发送一次任务的执行状态,任务子类发送本身的状态信息给主程序。
示例代码以下:
StatisticWorkJob.cs public class StatisticWorkJob:BaseJob { private ILog log = null; private string connStr = ""; private StatisticWorkDb db = null; private int sleepTime = 2000; public StatisticWorkJob(string name) { Init(name); } public override void Init(string name) { base.Init(name); log = LogManager.GetLogger("StatisticWorkJob"); } public override bool Start(int sleep = 1000) { log.Info("Start"); bool ret = false; ret = ReadConfigFile(); if (!ret) { log.Error("ReadConfigFile is false and return"); ReportWorkState(2, 1); return false; } db = new StatisticWorkDb(connStr); return base.Start(sleepTime); } public override bool Stop() { return base.Stop(); } public override void Run() { while(running) { //第一件事 更新全部的区的医疗服务中心数量 DoThingsUpdateAllMedicalServiceNum(); //第二件事 更新全部的科室的设备数量 DoThingUpdateAllMedicalDeviceNum(); //第三件事 更新全部的统计诊端表 DoThingUpdateAllDiagnosNum(); //Thread.Sleep(sleepTime); base.Run(); } } private void DoThingUpdateAllDiagnosNum() { try { //throw new NotImplementedException(); } catch(Exception e) { log.Error("DoThingUpdateAllDiagnosNum:error:" + e.Message); ReportWorkState(2, 1); } } private void DoThingUpdateAllMedicalDeviceNum() { try { } catch(Exception e) { log.Error("DoThingUpdateAllMedicalDeviceNum:error:" + e.Message); ReportWorkState(2, 1); } } private void DoThingsUpdateAllMedicalServiceNum() { try { } catch (Exception e) { log.Error("DoThingsUpdateAllMedicalServiceNum:error:" + e.Message); ReportWorkState(2, 1); } } private bool ReadConfigFile() { bool ret = false; XmlHelperEx xmlHelper = new XmlHelperEx(); try { if (xmlHelper.LoadXmlFile(configDirectory + "config.xml")) { //加载连接字符串 connStr = xmlHelper.GetValue("root/connectionStrings"); sleepTime = Convert.ToInt32(xmlHelper.GetValue("root/sleeptime")); ret = true; } } catch { log.Error("LoadXmlFile:" + configDirectory + "config.xml"); ReportWorkState(2, 1); } return ret; } } BaseJob.cs public class BaseJob { public string jsonName = ""; public Thread td = null; public bool running = false; private int sleepTimeState = 1000; public int sleepTimeWork = 1000; private int sleepTemp = 0; public string workName = string.Empty; public string configDirectory = string.Empty; public delegate void DelagateWorkState(string name,int code,int cnt); public event DelagateWorkState evetWorkState = null; public virtual void Init(string name) { workName = name; configDirectory = System.AppDomain.CurrentDomain.BaseDirectory; } public void SetConfigDirectory(string dir) { configDirectory = dir; } public string GetConfigDirectory() { return configDirectory; } public virtual bool Start(int sleep = 1000) { bool ret = false; if (!running) { sleepTimeWork = sleep; try { running = true; td = new System.Threading.Thread(Run); td.Start(); ret = true; } catch { ret = false; } } return ret; } public virtual bool Stop() { bool ret = false; if(running) { try { if (td != null) { running = false; td.Abort(); ret = true; } } catch { ret = false; } } return ret; } public string GetWorkName() { return workName; } private int WaitingWorkTime() { int sleeptime = 0; if(sleepTimeWork < sleepTimeState) { sleeptime = sleepTimeWork; } else { if(sleepTemp + sleepTimeState >= sleepTimeWork) { sleeptime = sleepTemp + sleepTimeState - sleepTimeWork; sleepTemp = 0; } else { sleeptime = sleepTimeState; sleepTemp += sleepTimeState; } } return sleeptime; } public void ReportWorkState(int code,int cnt) { if(evetWorkState != null) { evetWorkState(workName,code,cnt); } } public virtual void Run() { int sleeptime = WaitingWorkTime(); ReportWorkState(1,1); Thread.Sleep(sleeptime); } }