1. 程式人生 > >C#中定時器Timer與DispatcherTimer的用法

C#中定時器Timer與DispatcherTimer的用法

最近的工作專案中需要定時更新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         {
12
InitializeComponent(); 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 }

輸出結果如下,可以看出程式能夠正常的執行