1. DispatcherTimer
在System.Windows.Threading中,在Tick事件中可直接处理UI线程中的事务。
2. System.Timers.Timer
Elapsed事件在独立线程中,需要Invoke方法处理UI线程中的事务。
3. System.Threading.Timer
TimerCallback在独立线程中,需要Invoke方法处理UI线程中的事务。
在WPF中,DispatcherTimer使用最简便,但会受一些情况影响(如Thread.Sleep(1000)); 另外两种定时精度更高。
推荐使用System.Timers.Timer。
前台代码:
<Window x:Class="WPF_Timer.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WPF_Timer"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="500"
WindowStartupLocation="CenterScreen" Loaded="Window_Loaded" Closed="Window_Closed">
<Grid>
<StackPanel>
<Border Background="Green" BorderThickness="5" BorderBrush="Black">
<ListBox Name="listBox" Height="320" Margin="10"/>
</Border>
<Button Name="btnStart" Content="START" Margin="0,10" Click="btnStart_Click"/>
<Button Name="btnStop" Content="STOP" Click="btnStop_Click" />
</StackPanel>
</Grid>
</Window>
后台代码:
using System;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Threading; //DispatcherTimer
using System.Timers; //Timer
using System.Threading; //stTimer
namespace WPF_Timer
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
ObservableCollection<string> lst; //绑定ListBox 双向
DispatcherTimer dpTimer; //在UI线程中,当UI线程暂停时,dpTimer也会中断。
System.Timers.Timer timer; //在独立thread中
System.Threading.Timer stTimer; //在独立thread中
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
lst = new ObservableCollection<string>();
listBox.ItemsSource = lst;
//dptimer = new DispatcherTimer();
//dptimer.Interval = TimeSpan.FromSeconds(2);
//dptimer.Tick += Dptimer_Tick;
//timer = new System.Timers.Timer(2000); //2000ms
//timer.Elapsed += Timer_Elapsed;
stTimer = new System.Threading.Timer(new TimerCallback(timer_OnTime), null, -1, 2000);
}
private void timer_OnTime(object state) //System.Threading.Timer
{
Dispatcher.Invoke(new Action(() => { lst.Add(DateTime.Now.ToString()); }));
}
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
Dispatcher.Invoke(new Action(() => { lst.Add(DateTime.Now.ToString()); }));
//throw new NotImplementedException();
}
private void Dptimer_Tick(object sender, EventArgs e)
{
lst.Add(DateTime.Now.ToString());
//throw new NotImplementedException();
}
private void btnStart_Click(object sender, RoutedEventArgs e)
{
//dptimer.Start();
//timer.Start();
stTimer.Change(0, 2000);
}
private void btnStop_Click(object sender, RoutedEventArgs e)
{
//dptimer.Stop();
//timer.Stop();
stTimer.Change(-1, 2000);
}
private void Window_Closed(object sender, EventArgs e)
{
//if (dptimer != null) dptimer.Stop();
//if (timer != null) timer.Stop();
if (stTimer != null) stTimer.Change(-1, 2000);
}
}
}