該框架設計主要用於後臺執行任務,只須要動態的去添加執行任務便可,而不須要關心任務開始、中止以及任務狀態信息等。旨在更加方便的去管理多個任務。數據庫
任務集框架設置圖以下,主要分爲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); } }