SYSTEM.WINDOWS.FORMS.TIMER與SYSTEM.TIMERS.TIMER的區別
.NET Framework裡面提供了三種Timer:
System.Windows.Forms.Timer
System.Timers.Timer
System.Threading.Timer
VS.Net 2005預設只有一個Timer控制項,但那是System.Forms.Timer控制項。如果要使用System.Timers.Timer的控制項,需要在工具箱上按一下右鍵,手動添加的步驟:工具箱按一下右鍵->Add Item->找到命名空間是System.Timers.Timer的控制項,將其選中,OK即可。
這裡簡單的介紹一下這兩種Timer的區別。
System.Windows.Forms.Timer是使用得比較多的Timer,Timer Start之後定時(按設定的Interval)調用掛接在Tick事件上的EventHandler。在這種Timer的EventHandler中可以直接獲取和修改UI元素而不會出現問題,因為這種Timer實際上就是在UI執行緒自身上進行調用的。也正是因為這個原因,導致了在Timer的EventHandler裡面進行長時間的阻塞調用,將會阻塞介面回應的後果。下面是一個簡單的例子:
Timer timer1 = new Timer();
private void Form1_Load(object sender,
EventArgs e)
{
timer1.Interval = 3000;
timer1.Tick += delegate(object o, EventArgs args)
{
DoWork();
};
timer1.Start();
}
private void DoWork()
{
for (int i = 0; i < 10; i++)
{
System.Threading.Thread.Sleep(1000);
}
}
在這個例子中,DoWork方法裡面將會阻塞10秒,在這10秒之內,UI將會失去回應。而通過使用System.Timers.Timer,就可以解決這個問題。因為System.Timers.Timer是在.NET的Thread Pool上面運行的,而不是直接在UI
Thread上面運行,所以在這種Timer的EventHandler裡面進行耗時較長的計算不會導致UI失去回應。
但是這裡有兩個地方需要注意:
一、因為一般來說System.Timers.Timer不是運行在UI Thread上面的,所以如果要在這種Timer的EventHandler裡面更新UI元素的話,需要進行一次執行緒切換,在WinForm開發中一般通過UI元素的Invoke方法完成:
private void DoWork()
{
for (int i = 0; i < 10; i++)
{
System.Threading.Thread.Sleep(1000);
}
this.Invoke(new UpdateUICallBack(UpdateUI));
}
private delegate void UpdateUICallBack();
private void UpdateUI()
{
}
二、System.Timers.Timer有一個Property:SynchronizingObject 。如果設置了這個Property(一般是某個Form),那麼之後對Timer掛接的EventHandler的調用將會在創建這個UI元素的執行緒上進
行(一般來說就是UI執行緒)。值得注意的是,如果你通過WinForm設計器把System.Timers.Timer拖放到Form上,那麼這個 Property將會自動被設置。此時這種Timer就和System.Windows.Forms.Timer的效果一樣:長調用將會阻塞介面。
總結:
System.Windows.Forms.Timer
1. 它是一個基於Form的計時器
2. 創建之後,你可以使用Interval設置Tick之間的跨度,用委託(delegate)hook Tick事件
3. 調用Start和Stop方法,開始和停止
4. 完全基於UI執行緒,因此部分UI相關的操作會在這個計時器內進行
5. 長時間的UI操作可能導致部分Tick丟失
System.Timers.Timer
1. 用的不是Tick事件,而是Elapsed事件
2. 和System.Windows.Forms.Timer一樣,用Start和Stop方法
3. AutoReset屬性決定計時器是不是要發起一次事件然後停止,還是進入開始/等待的迴圈。System.Windows.Forms.Timer沒有這個屬性
4. 設置對於UI控制項的同步物件(synchronizing object),對控制項的UI執行緒發起事件
System.Windows.Forms.Timer 是對於使用者介面程式設計的比較顯然的選擇。而另外兩個之間的選擇就不是很明顯。如果必須在IContainer內,那麼就應該選擇 System.Timers.Timer。如果沒有用到System.Timers.Timer的特性,那麼建議選擇 System.Threading.Timer,因為它稍稍羽量級一些。
Timer 是先等待再執行,如果我們要達到先執行再等待的效果,設置 默認時間間隔Interval =100,或者更少為1(不能為0),之後再引發事件內更改 時間間隔Interval 為想要的值。
轉載自:http://www.cnblogs.com/lonelyxmas/archive/2009/10/27/1590604.html
沒有留言:
張貼留言