任务集框架的设计
任务集框架的设计
任务集框架的设计意图
该框架设计主要用于后台执行任务,只需要动态的去添加执行任务即可,而不需要关心任务开始、停止以及任务状态信息等。旨在更加方便的去管理多个任务。
任务集框架的设计图
任务集框架设置图如下,主要分为4大模块,config、log、help、task 这四个模块。
Config 模块主要是各个任务的配置文件。
Log模块主要是记录各个任务产生的日志文件。
Helper模块主要是所有的任务需要用到的工具集。
Tasks 模块主要是各个任务的集合
任务集框架的设计模块详解
1. 主程序模块
该模块主要用于任务框架开启停止的入口,同时配置界面,可以在框架运行过程中手动
开启,停止任务以及配置任务。通过界面展示,可以详细的看到任务的执行次数,错误次数以及任务的当前状态。界面如下:
任务状态:表示任务当前的执行状态。表示当前任务未开启,表示当前任务已暂停,表示当前任务正在运行中。
任务次数:表示当前任务总共执行的次数。
错误次数:表示当前任务总共执行的错误次数
任务周期:表示当前任务执行了多少个任务周期,一个周期是86400个任务次数。
2. Config模块
该模块用于所有的任务的配置。
示例如下:
<?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>
3. Log模块
该模块用于记录所有的任务在运行期间的日志数据。该模块使用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:拒绝访问。
4. Helper 模块
该模块主要是一些工具的集合,该项目中目前存放一些数据库的操作类,以及XML 文
档的操作类等。
5. Tasks模块
该模块是所有的任务执行实体,每个任务继承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); } }