1. 程式人生 > >System.Windows.Forms.Timer與System.Timers.Timer的區別

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事件上的EvnetHandler。在這種Timer的EventHandler中可 以直接獲取和修改UI元素而不會出現問題--因為這種Timer實際上就是在UI執行緒自身上進行呼叫的。也正是因為這個原因,導致了在Timer的 EventHandler裡面進行長時間的阻塞呼叫,將會阻塞介面響應的後果。下面是一個簡單的例子:

public class MainForm : Form
{

private void MainForm_Load(object sender, EventArgs e)
{
timer.Interval = 1000;
timer.Tick += delegate(object o, EventArgs args)
{
DoWork();
};
timer.Start();
}

private void DoWork()
{
for (int i = 0; i < 10; i++)
{
System.Threading.Thread.Sleep(1000);
}
}
System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
}

在這個例子中,DoWork方法裡面將會阻塞10秒,在這10秒之內,UI將會失去響應。而通過使用System.Timers.Timer,就可 以解決這個問題。因為System.Timers.Timer是在.NET的Thread Pool上面執行的,而不是直接在UI Thread上面執行,所以在這種Timer的EventHandler裡面進行耗時較長的計算不會導致UI失去響應。但是這裡有兩個地方需要注意:

  1. 因為一般來說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()
    {
    }

  2. 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.Threading.Timer的區別比較見http://mark.michaelis.net/Blog/SystemWindowsFormsTimerVsSystemThreadingTimerVsSystemTimersTimer.aspx,這裡只摘錄最後的總結:
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