不像我開始描述的兩個定時器類SystemThreadingTimer有四個重載構造函數就像下面這樣
public Timer(TimerCallback callback
object state
long dueTime
long period);
public Timer(TimerCallback callback
object state
UInt
dueTime
UInt
period);
public Timer(TimerCallback callback
object state
int dueTime
int period);
public Timer(TimerCallback callback
object state
TimeSpan dueTime
TimeSpan period);
第一個參數(callback)要求一個TimerCallback的委托它指向一個方法該方法具有下面的結構
public void TimerCallback(object state);
第二個參數(state)可以為空或者是包含程序規范信息的對象在每一個定時器事件被調用時該state對象作為一個參數傳遞給你的定時回調函數記住定時回調功能是在一個工作者線程上執行的所以你必須確保訪問state對象的線程安全
第三個參數(dueTime)讓你定義一個引發初始定時器事件的時間你可指定一個立即開始定時器或者阻止定時器自動的開始你可以使用SystemThreadingTimeoutInfinite常量
第四個參數(period)讓你定義一個回調函數被調用的時間間隔(毫秒)給該參數定義一個或者TimeoutInfinite可以阻止後續的定時器事件調用
一旦構造函數被調用你仍然可以通過Change方法改變dueTime和period該方法有下面四種重載形式
public bool Change(int dueTime
int period);public bool Change(uint dueTime
uint period);public bool Change(long dueTime
long period);public bool Change(TimeSpan dueTime
TimeSpan period);
下面是我在例子程序中用到的開始和停止該定時器的代碼
//Initialize the timer to not start automatically
System
Threading
Timer tmrThreadingTimer = newSystem
Threading
Timer(new TimerCallback(tmrThreadingTimer_TimerCallback)
null
System
Threading
Timeout
Infinite
);
//Manually start the timer
tmrThreadingTimer
Change(
);
//Manually stop the timer
tmrThreadingTimer
Change(Timeout
Infinte
Timeout
Infinite);
正如你所期望的那樣通過選擇SystemThreadingTimer類運行例子程序會產生同你看到的SystemTimersTimer類一樣的輸出結果因為TimerCallback功能也是在工作者線程上被調用沒有一個跳動被跳過(假設有工作者線程可用)Figure 顯示了例子程序的輸出結果
不像SystemTimersTimer類沒有與SynchronizingObject相對應的屬性被提供任何請求訪問UI控件的操作都必須通過控件的Invoke或BeginInvoke方法被列集
定時器的線程安全編程
為了最大限度的代碼重用三種不同類型的定時器事件都調用了同樣的ShowTimerEventFired方法下面就是三個定時器事件的處理函數
private void tmrWindowsFormsTimer_Tick(object sender SystemEventArgse)
{
ShowTimerEventFired(DateTimeNow GetThreadName());
}
private void tmrTimersTimer_Elapsed(object sender SystemTimersElapsedEventArgse){
ShowTimerEventFired(DateTimeNow GetThreadName());
}
private void tmrThreadingTimer_TimerCallback(object state){ ShowTimerEventFired(DateTimeNow GetThreadName());
}
正如你所看到的ShowTimerEventFired方法采用當前時間和當前線程名字作為參數為了區別工作者線程和UI線程在例子程序的主入口點設置CurrentThread對象的名字屬性為UIThreadGetThreadName幫助函數返回ThreadCurrentThreadName值或者當ThreadCurrentThreadIsThreadPoolThread屬性為真時返回WorkerThread
因為SystemTimersTimer和SystemThreadingTimer的定時器事件都是在工作者線程上執行的所以在事件處理函數中的任何用戶交互代碼都不是馬上進行的而是被列集等候返回到UI線程上進行處理為了這樣做我創建了一個ShowTimerEventFiredDelegate委托調用
private delegate void ShowTimerEventFiredDelegate (DateTime eventTime
string threadName);
[] [] [] []
From:http://tw.wingwit.com/Article/program/net/201311/15305.html