国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

自定義定時組件

2019-11-17 02:58:19
字體:
來源:轉載
供稿:網友

自定義定時組件

  工作了這么久,封裝過一部分Helper,也寫過一些控件,但也沒寫過屬于自己的框架,這次寫的這個我覺得是一個組件而已,是一個定時組件。是一個定時器組件,有別于.NET Framework里面提供的幾個Timer。首先說說背景,就發現現在手頭上的工作離不開定時,定時做一個任務,什么都是定時去做什么什么,隔某段時間干某件事情,都離不開“定時”這個詞。眾所周知這個要用到多線程,在多篇關于多線程的文章里面有提過做一些周期性的操作時最好用Timer,當然這個Timer肯定是Threading.Timer,并不是WinForm控件里面的Timer。但我覺得在我的應用中Timer不夠滿足需求。

1.Timer只能在做任務與任務之間相隔一段時間的操作,如下圖

但我需要的是這次任務開始的時刻到下次任務開始時刻是相隔同等的時間,又如下圖

這樣的情況下Timer則不能滿足需求。

2.Timer的時間間隔一般是定的,但是如果要每次執行完任務要變動一下休眠的時間, 則需要調用Timer的Change方法。

3.Timer的休眠時間不是通過整形確定休眠的毫秒數,就是用一個TimeSpan來確定,對于那種到每天多少多少時刻或者到每小時的多少分執行一次的任務來說也不能夠完全方便使用

對于上面這三種,鄙人對定時器封裝了一下,棄用了Timer,還是用回了原有的Thread,定義了一種描述重復時間的模式字符串,計算出TimeSpan,從而調用Thread的Sleep()方法來休眠。下面展示整個組件的類圖

最底下是兩個關于時間計算方面的類,兩個代理是兩種任務方法的委托,基類BaseCycleMission是周期任務的積累,實現了ICycle接口,主要進行對任務線程的操控(開始,停止等),繼承他的兩個子類一個是實現上文第一點中我后來描述那種需求,一個類似于原有Timer的功能。它們各自使用不同的委托。MissionManager只是對所有周期任務的一個管理,統一去開啟或暫停某一類的任務。

時間計算模塊

  那首先來介紹一下定義的字符串模式。現在遇到的周期是有兩種模式,

  • 一種是每隔多長時間要執行一次的任務,這個是最普通的周期形式,以每個5分鐘為例,完整的形式是“-99--99--99 -99:05:00”,“-99”是缺省的意思,當然還有其他簡寫的模式;
  • 另一種是沒到什么什么時候執行一次任務,例如沒到中午12點為例完整的形式是“ff-ff-ff 12: ff:ff”,“ff”是默認的形式,當然也可以用“FF”,這里也有其他簡寫的模式。

所有字符串的模式如下表所示

 

每到***時刻

每隔***時間

完整

ffff-ff-ff ff:ff:ff 或 ff-ff-ff ff:ff:ff

-99--99--99 -99:-99:-99

日期部分

ffff-ff-ff 或 ff-ff-ff

-99--99--99

時間部分

ff:ff:ff 或 ff:ff:ff

-99:-99:-99

時間簡寫

ff:ff 或 ff:ff

-99:-99

  那么時間計算模塊的處理流程是,給定了相應的模式字符串,TimePointConverter借助正則表達式匹配出對應的模式,返回匹配出來的年月日時分秒各個值,得出結果之后就調用SleepTimePRovider來計算出線程所要休眠的時間。下面則展示一下兩個類的部分代碼

 1     public class TimePointConverter 2     { 3         //其他成員 4         private int[] DateTimeFixBuilder(string timeStr) 5         { 6             int[] result = null; 7  8             string[] dtArray = timeStr.Split(); 9             string[] dateArray = dtArray[0].Split('-');10             string[] timeArray = dtArray[1].Split(':');11 12             uint year,month,date;13             uint hour, minute, second; 14             uint.TryParse(dateArray[0], out year);15             uint.TryParse(dateArray[1], out month);16             uint.TryParse(dateArray[2], out date);17 18             uint.TryParse(timeArray[0], out hour);19             uint.TryParse(timeArray[1], out minute);20             uint.TryParse(timeArray[2], out second);21 22             //return InnerFixBuilder(year, month, date, hour, minute, second);23             result = new int[] { (int)year, (int)month, (int)date, (int)hour, (int)minute, (int)second };24             return result;25         }26         //其他成員27     }
 1     public class SleepTimeProvider 2 { 3         //其他成員 4         public TimeSpan InnerFixBuilder(uint year, uint month, uint date, uint hour, uint minute, uint second) 5                 { 6             uint[] uintTimeArray = new uint[6] { year, month, date, hour, minute, second }; 7             int[] intNowArray = new int[6]  8             {    9                 DateTime.Now.Year,DateTime.Now.Month,DateTime.Now.Day,10                 DateTime.Now.Hour,DateTime.Now.Minute,DateTime.Now.Second 11             };12             int[] intTimeArray = new int[6];13 14             intTimeArray[0] = uintTimeArray[0] == 0 ? -DateTime.Now.Year : (int)uintTimeArray[0];15             for (int i = 1; i < uintTimeArray.Length; i++)16             {17                 intTimeArray[i] = intTimeArray[i - 1] < 0 && uintTimeArray[i] == 0 ?18                     -intNowArray[i] : (int)uintTimeArray[i];19             }20             DateTime goalTime = new DateTime(Math.Abs(intTimeArray[0]),21                 Math.Abs(intTimeArray[1]),22                 Math.Abs(intTimeArray[2]),23                 Math.Abs(intTimeArray[3]),24                 Math.Abs(intTimeArray[4]),25                 Math.Abs(intTimeArray[5]));26 27 28             if (goalTime < DateTime.Now)29             {30                 int max = -1;31                 for (int i = intTimeArray.Length - 1; i >= 0; i--)32                 {33                     if (intTimeArray[i] < 0 && i > max)34                     {35                         max = i;36                         intTimeArray[i]--;37                     }38                     intTimeArray[i] = Math.Abs(intTimeArray[i]);39                 }40                 goalTime = new DateTime(Math.Abs(intTimeArray[0]),41                 Math.Abs(intTimeArray[1]),42                 Math.Abs(intTimeArray[2]),43                 Math.Abs(intTimeArray[3]),44                 Math.Abs(intTimeArray[4]),45                 Math.Abs(intTimeArray[5]));46             }47             return goalTime - DateTime.Now;48         }49 50         //其他成員51 }

線程調用模塊

  線程調用模塊是任務執行的核心部分,MissionEntiy是對線程操作的封裝,主要負責開始,停止,暫停等操作。Thread用的是后臺線程,對線程操作時也多做幾個判斷。例如暫停那個操作的定義如下

 1         public bool Pause() 2         { 3             if (actionThread == null) return false; 4             if (actionThread.ThreadState == (System.Threading.ThreadState.Running | ThreadState.Background) || 5                 actionThread.ThreadState == (System.Threading.ThreadState.WaitSleepJoin | ThreadState.Background)) 6             { 7                 actionThread.Suspend(); 8                 return true; 9             }10             return false;11         }

  CycleMission是真正的任務載體,里面都同樣有對線程的操作,但是又外加了一些時間處理,最核心的是讓線程的BuildMainAction方法,這個方法是計算出要休眠的時間,讓線程休眠,到點時調用適當的方法委托。

  1     public class BaseCycleMission:ICycleMission  2     {  3         //其他成員  4   5         protected void BuildMainAction(string normalCycle, string overTimeCycle, object overTimeDelegate, bool isSleepBefore, bool isInclude)  6         {  7             mainAction = () =>  8             {  9                 TimeSpan sleepTime = TimeSpan.MinValue; 10                 TimeSpan overTime = TimeSpan.MinValue; 11                 bool result = true; 12                 TimePointConvert.CircleType type; 13  14                 #region 提前休眠 15                 if (isSleepBefore) 16                 { 17                     type = TimePointConvert.Default.PraseType(normalCycle); 18  19                     if (type ==
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 汶川县| 永宁县| 临城县| 定南县| 卓资县| 且末县| 灵台县| 东兴市| 仁寿县| 商丘市| 洱源县| 措美县| 大竹县| 南澳县| 昌都县| 清镇市| 师宗县| 伊川县| 高雄县| 牡丹江市| 敦煌市| 闽侯县| 朝阳区| 米易县| 瑞昌市| 巧家县| 彭阳县| 宣武区| 朔州市| 池州市| 安远县| 大同县| 高要市| 新郑市| 常熟市| 南岸区| 紫云| 京山县| 连南| 手游| 白玉县|