自定義定時元件

2021-09-06 17:38:06 字數 4765 閱讀 8532

工作了這麼久,封裝過一部分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只是對所有週期任務的乙個管理,統一去開啟或暫停某一類的任務。

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

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

每到***時刻

每隔***時間

完整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

timepointconverter2;

24return

result;25}

26//

其他成員

27 }

1

public

class

sleeptimeprovider2;

7int intnowarray = new

int[6] 8

;12int 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++)

1620 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

]));

2627

28if (goaltime

2938 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}

47return goaltime -datetime.now;48}

4950

//其他成員

51 }

執行緒呼叫模組是任務執行的核心部分,missionentiy是對執行緒操作的封裝,主要負責開始,停止,暫停等操作。thread用的是後台執行緒,對執行緒操作時也多做幾個判斷。例如暫停那個操作的定義如下

1

public

bool

pause()210

return

false

;11 }

cyclemission是真正的任務載體,裡面都同樣有對執行緒的操作,但是又外加了一些時間處理,最核心的是讓執行緒的buildmainaction方法,這個方法是計算出要休眠的時間,讓執行緒休眠,到點時呼叫適當的方法委託。

1

public

class

basecyclemission:icyclemission228

#endregion

2930

while (true)31

54#endregion

5556

#region 執行方法

57if (overtimedelegate is

overtimecycledelegate)

58 result = (overtimedelegate as

overtimecycledelegate).invoke();

59else

6064

#endregion

6566

#region 計算時間

67if (!isinclude)

6888

#endregion

8990

91if

(result)

9296

else

97101

}102

};103

}104

105//

其他成員

106 }

當然呼叫不是呼叫這個方法,呼叫只是呼叫它兩個幾類exceptcyclemission和includecyclemission,分別代表任務執行的時間不包括在週期裡面和包括在週期裡面兩種。

管理器主要是乙個字典集,是乙個icyclemission和字串的字典集,裡面包含了對集合裡面所有元素的操作:增加,刪除,執行,恢復,暫停,停止。除了刪除和增加,其他都包含了類似下面的方法

runallmission()

runallincludecyclemission()

runallexceptcyclemission()

ru****sionamong(

params

string

missionnames)

ru****sionexcept(

params

string missionnames)

但是這堆方法裡面都呼叫了callaction這個方法,

private

void callaction(ienumerablemissioncollection,action method)

}

例如在runallexceptcyclemission()方法裡面呼叫如下

public

void

runallexceptcyclemission()

做這個元件應該是小題大做,畢竟看了那麼久的《mvc框架揭秘》手癢,寫了這個東西覺得框架裡面的結構要設計好,命名也要命名好。

自定義元件

myedittext 清除輸入的資料 setcompunddrawable 設定edittext ontouchevent ondraw 作用 繪製view顯示的內容,由系統自動呼叫 常用類 paint,canvas invalidate,postinvalidate 貪吃蛇原理 改變集合中的資料,...

自定義元件

自定義控制項 1.抽取layout如 list item home.xml 2.寫乙個類繼承1中的layout,實現父類 相對布局 的構造方法 3.使用 自定義控制項的屬性 1.布局檔案裡自定義乙個命名空間 xmlns my 2.在res的values目錄下描述自定義屬性的檔案 3.在布局檔案裡寫你...

自定義元件

自定義控制項 1.抽取layout如 list item home.xml 2.寫乙個類繼承1中的layout,實現父類 相對布局 的構造方法 3.使用 自定義控制項的屬性 1.布局檔案裡自定義乙個命名空間 xmlns my 2.在res的values目錄下描述自定義屬性的檔案 3.在布局檔案裡寫你...