delphi 自帶的Timer控件,使用方便,但它的 OnTimer 事件是在主線程中引起的。html
若是在事件中執行較耗時的代碼,會引發主界面假死。故實現一個線程的Timer就有必要了。ide
TThreadTimer 基於 TSimpleThread 繼承而來。學習
本例源碼下載spa
unit uThreadTimer; interface uses uSimpleThread; type TThreadTimer = class; // 提早申明 TThreadTimer 是一個類 TOnThreadTimer = procedure(Sender: TThreadTimer) of object; // 此處就能夠引用 TThreadTimer,這種寫法避免將 Sender 寫爲 TObject; // 爲何要寫這個 sender ,主要是爲了區別是誰引起了事件,而且 sender 上能夠帶參數 // 方便進一步使用 TThreadTimer = Class(TSimpleThread) private FInterval: Cardinal; FOnThreadTimer: TOnThreadTimer; procedure CountTimer; procedure DoCountTimer; procedure SetInterval(val: Cardinal); procedure SetOnThreadTimer(val: TOnThreadTimer); procedure DoOnThreadTimer; // 請學習此寫法 public constructor Create(AAllowActiveX: Boolean = false); // AAlowActiveX 在父類中有說明 procedure StartThread; override; // 重載父類的 StartThread property Interval: Cardinal read FInterval write SetInterval default 1000; // 這個 default 1000 是給人看的,不會產生實際做用。 // 故還須要在 Create 事件中指定 FInterval:=1000; // 若是可視化控件的 published 塊中,此值會顯示在屬性編輯框中 property OnThreadTimer: TOnThreadTimer read FOnThreadTimer write SetOnThreadTimer; End; implementation { TThreadTimer } procedure TThreadTimer.CountTimer; begin ExeProcInThread(DoCountTimer); // 將 DoCountTimer 置入線程中去執行 // 這是 TSimpleThread 的用法 end; constructor TThreadTimer.Create(AAllowActiveX: Boolean); begin inherited Create(AAllowActiveX); FInterval := 1000; // 默認間隔時間爲 1 秒 end; procedure TThreadTimer.DoCountTimer; begin if WaitStop then // 這是父類的一個屬性,表示線程如今須要中止了。 exit; SleepExceptStopped(FInterval); // sleep 指定的時間,若是中途接到退出指令,則立刻響應。 // 父類中有源碼,可看一看 if not WaitStop then begin DoOnThreadTimer; // 引起時間到事件 end; CountTimer; // 再次在線程中執行 DoCountTimer; // 父類已經設計好了,就這樣簡單地調用,便可實如今線程中執行本過程,但又不會引發「遞歸」 end; procedure TThreadTimer.DoOnThreadTimer; begin if Assigned(FOnThreadTimer) then FOnThreadTimer(Self); // 把這句寫爲一個過程,看似囉嗦,但爲了程序可讀性,是值得的。 end; procedure TThreadTimer.StartThread; begin inherited; CountTimer; // 啓動計時 end; procedure TThreadTimer.SetInterval(val: Cardinal); begin FInterval := val; end; procedure TThreadTimer.SetOnThreadTimer(val: TOnThreadTimer); begin FOnThreadTimer := val; end; end. uThreadTimer.pas