C#中定時器Timer與DispatcherTimer的用法
阿新 • • 發佈:2019-01-10
最近的工作專案中需要定時更新UI控制元件中的資料,這時候第一反應肯定會想到去使用System.Timers.Timer定時更新UI控制元件,但是程式執行後,會發現程式崩潰了。報的異常為“呼叫執行緒無法訪問此物件,因為另一個執行緒擁有該物件。”,網上查找了原因,Timer的觸發事件與UI不是屬於同一個執行緒,所以說在Timer的觸發事件去更新UI時,會造成UI物件被佔用的問題。網上說,可以嘗試用DispatcherTimer這個定時器去更新UI,於是我做個一個demo測試了一下,果然是可行的。
上面是一個WPF視窗,點選計時按鈕,編輯框中顯示計時次數
1.使用System.Timers.Timer更新編輯框中的資料
1 namespace Timer 2 { 3 /// <summary> 4 /// MainWindow.xaml 的互動邏輯 5 /// </summary> 6 public partial class MainWindow : Window 7 { 8 System.Timers.Timer timer = null; 9 private static int nCount = 0; 10 public MainWindow() 11 { 12InitializeComponent(); 13 timer = new System.Timers.Timer(1000); 14 timer.AutoReset = true; 15 timer.Elapsed += new ElapsedEventHandler(TimeAction); 16 } 17 private void TimeAction(object sender, ElapsedEventArgs e) 18 { 19 if(!String.IsNullOrEmpty(txt_TimeCount.Text)) 20 { 21 //計時次數大於10時,則關閉定時器 22 if (Convert.ToInt32(txt_TimeCount.Text) > 10) 23 { 24 timer.Stop(); 25 } 26 } 27 28 txt_TimeCount.Text = Convert.ToString(nCount++); 29 } 30 private void btn_Time_Click(object sender, RoutedEventArgs e) 31 { 32 timer.Start(); 33 } 34 } 35 }
當點選按鈕後,會很明顯的出現上述所說的異常問題
2.使用DispatcherTimer更新編輯框中的資料
1 namespace Timer 2 { 3 /// <summary> 4 /// MainWindow.xaml 的互動邏輯 5 /// </summary> 6 public partial class MainWindow : Window 7 { 8 DispatcherTimer dispatcherTimer = null; 9 private static int nCount = 0; 10 public MainWindow() 11 { 12 InitializeComponent(); 13 dispatcherTimer = new DispatcherTimer(); 14 dispatcherTimer.Interval = new TimeSpan(0, 0, 1); 15 dispatcherTimer.Tick += new EventHandler(TimeAction); 16 17 } 18 19 private void TimeAction(object sender, EventArgs e) 20 { 21 if (!String.IsNullOrEmpty(txt_TimeCount.Text)) 22 { 23 //計時次數大於10時,則關閉定時器 24 if (Convert.ToInt32(txt_TimeCount.Text) > 10) 25 { 26 dispatcherTimer.Stop(); 27 } 28 } 29 30 txt_TimeCount.Text = Convert.ToString(nCount++); 31 } 32 private void btn_Time_Click(object sender, RoutedEventArgs e) 33 { 34 dispatcherTimer.Start(); 35 } 36 } 37 }
輸出結果如下,可以看出程式能夠正常的執行