在之前的文章中我們介紹過兩種Timer和BackgroundWorker組件,在上文中我們提到過,強烈建議在UI 線程上操作控件,否則很容易產生人品問題。可以想到,上次介紹的兩個Timer基於ThreadPool,回調方 法運行於不同於UI線程的新線程上,在這個方法中操作控件需要進行 Invoke或BeginInvoke。其實,還有 第三種System.Windows.Forms.Timer,它可以讓回調事件在UI線程上執行,我們來做一個實驗比較一下 System.Windows.Forms.Timer和System.Timers.Timer。在一個窗體上新建兩個標簽控件,然後來創建兩 個計時器:
private System.Windows.Forms.Timer timer1 = new System.Windows.Forms.Timer ();
private System.Timers.Timer timer2 = new System.Timers.Timer();
public Form2()
{
InitializeComponent();
}
雙擊表單,在Load事件中寫如下代碼:
this.Text = string.Concat("#", Thread.CurrentThread.ManagedThreadId);
//timer2.SynchronizingObject = this;
timer2.Interval = 1000;
timer2.Elapsed += new System.Timers.ElapsedEventHandler(timer2_Elapsed);
timer2.Enabled = true;
timer1.Interval = 1000;
timer1.Tick += new System.EventHandler(this.timer1_Tick);
timer1.Enabled = true;
然後是兩個計時器的處理方法:
private void timer1_Tick(object sender, EventArgs e)
{
label1.Text = string.Format("timer1 : #{0} {1} {2}", Thread.CurrentThread.ManagedThreadId, this.InvokeRequired, DateTime.Now.ToString());
}
private void timer2_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
label2.Text = string.Format("timer2 : #{0} {1} {2}", Thread.CurrentThread.ManagedThreadId, this.InvokeRequired, DateTime.Now.ToString());
}
以非調試方式運行程序,可以看到如下的結果: