实例对比WPF中的Timer和DispatcherTimer

时间:2022-06-25 20:38:55

本文使用Timer和DispatcherTimer制作电子时钟,通过实例对比来了解两者的本质区别。
下面是实例最终的运行画面。其中时钟1使用Timer实现,时钟2使用DispatcherTimer实现。
实例对比WPF中的Timer和DispatcherTimer
下面给出完整的实例代码(省略画面代码)。

using System;
using System.Windows;

namespace DispatcherTimereExp
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
System.Windows.Threading.DispatcherTimer dtimer;
System.Timers.Timer timer;
public MainWindow()
{
InitializeComponent();
if (dtimer == null)
{
dtimer = new System.Windows.Threading.DispatcherTimer();
dtimer.Interval = TimeSpan.FromSeconds(1);
dtimer.Tick += dtimer_Tick;
}
if (timer == null)
{
timer = new System.Timers.Timer();
timer.Interval = 1000;
timer.Elapsed += timer_Elapsed;
}
}

void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
this.Dispatcher.BeginInvoke(new Action(() =>
{
this.Label_OtherResult.Content = DateTime.Now.ToString();
}), null);
}

void dtimer_Tick(object sender, EventArgs e)
{
this.Label_Result.Content = DateTime.Now.ToString();
}

private void Button_Click_1(object sender, RoutedEventArgs e)
{
dtimer.Start();
timer.Start();
}
}
}

若将timer_Elapsed方法中的代码替换成dtimer_Tick方法中的代码,会出现异常“由于其他线程拥有此对象,因此调用线程无法对其进行访问。”这是因为Timer运行在非UI 线程,如果Timer需要更新UI画面,需要使用this.Dispatcher切换到UI线程后使用Invoke或者 BeginInvoke方法更新UI画面。而DispatcherTimer运行在UI 线程,可以直接更新UI画面。这便是两者本质的区别。