概述
C#中的框架中,为我们提供了几种定时器,其实是3类。下面就通过自己的学习和应用简单介绍下:
首先,定时器的原理:等待一段时间之后,开始执行任务;到了等待时间后,开始执行任务……一直循环。
System.Threading.Timer
简介
这个定时器是一个单独的线程,执行任务(定时器回调任务)的线程分配由线程池管理。如果要使用定时器,他是最好的选择。优点:独立线程,等待周期变化稳定,不会受其他线程(尤其是主线程)的影响。
使用
使用WPF作为开发平台,为了演示效果,首先我们做下面的事情——搭建一个UI界面,定时器开始时,刷新UI上的Slider
控件的Value
。
-
UI设计
<Window x:Class="Melphi.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:Melphi" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <Grid> <WrapPanel> <Border Width="200" Height="200" BorderBrush="Black" BorderThickness="1"> <StackPanel > <TextBlock FontSize="14" FontWeight="DemiBold" Text="System.Threading.Timer" Margin="5 10"/> <Grid Margin="5 10"> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <TextBlock Text="进度:" VerticalAlignment="Center"/> <Slider Grid.Column="1" x:Name="SliderProcessing" Maximum="100" HorizontalAlignment="Stretch"/> </Grid> <StackPanel Orientation="Horizontal" HorizontalAlignment="Center"> <Button x:Name="ButtonStart" Click="ButtonStart_Click" Content="Start" Margin="5 0"/> <Button x:Name="ButtonPause" Click="ButtonPause_Click" Content="Pause" Margin="5 0"/> </StackPanel> </StackPanel> </Border> </WrapPanel> </Grid> </Window>
-
定时器的定义和控制
using System; using System.Threading; using System.Windows; namespace Melphi { /// <summary> /// MainWindow.xaml 的交互逻辑 /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); // 初始化定时器 InitializeThreadingTimer(); } /// <summary> /// System.Threading.Timer 实例, /// 最推荐使用的定时器 /// </summary> private System.Threading.Timer mThreadingTimer; /// <summary> /// 初始化一个 System.Threading.Timer 定时器 /// </summary> private void InitializeThreadingTimer() { // 初始化一个定时器:具有回调函数,无状态的,不启动,不终止定时器 mThreadingTimer = new System.Threading.Timer(ThreadTimerCallback, null, Timeout.Infinite, Timeout.Infinite); } /// <summary> /// System.Threading.Timer 的回调方法 /// </summary> /// <param name="state"></param> private void ThreadTimerCallback(object state) { // 告诉定时器,等待多久执行一次回调 mThreadingTimer.Change(500, Timeout.Infinite); // TODO // 使用UI线程刷新数据刷新界面 this.Dispatcher.BeginInvoke(new Action(() => this.SliderProcessing.Value += 5), System.Windows.Threading.DispatcherPriority.Normal, null); } /// <summary> /// 开始 控制 System.Threading.Timer 定时器 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void ButtonStart_Click(object sender, RoutedEventArgs e) { // 马上启动定时器 mThreadingTimer.Change(0, Timeout.Infinite); } /// <summary> /// 暂停 控制 System.Threading.Timer 定时器 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void ButtonPause_Click(object sender, RoutedEventArgs e) { // 暂时停止定时器 mThreadingTimer.Change(Timeout.Infinite, Timeout.Infinite); } } }
-
效果
总结
可以System.Threading.Timer
的控制主要通过Change函数来实现。
System.Timers.Timer
简介
他的本质是System.Threading.Timer
类的包装器,计时器到期会触发,导致CLR将要处理的事件放到线程池队列中。因此它的任务执行也是一个单独的线程完成。但是他的弊端和BUG较多,因此开发过程中强烈建议不要使用、不要使用、不要使用。
使用
既然强烈建议不使用,这里我就不做它的使用示例了:)
System.Windows.Threading.DispatcherTimer
简介
这个WPF\Sliverlight平台特有的定时器,该定时器跟Windows的消息机制相关,它的调度与主线程息息相关,执行回调任务或者把定时器挂起等待等所有任务都是由主线程来完成。因此该定时器的准时性会受控于主线程空闲程度。优点:由于定时器执行 的任务是通过主线程来进行调度,因此可以直接在定时器内对主线程定义的对象(例如控件)直接操作。
使用
使用WPF作为开发平台,为了演示效果,首先我们做下面的事情——搭建一个UI界面,定时器开始时,刷新UI上的Slider
控件的Value
。和前面System.Threading.Timer
一毛一样哦。
-
UI
<Window x:Class="Melphi.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:Melphi" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <Grid> <WrapPanel> <!-- System.Threading.Timer --> <Border Width="200" Height="200" BorderBrush="Black" BorderThickness="1"> <StackPanel > <TextBlock FontSize="14" FontWeight="DemiBold" Text="System.Threading.Timer" Margin="5 10"/> <Grid Margin="5 10"> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <TextBlock Text="进度:" VerticalAlignment="Center"/> <Slider Grid.Column="1" x:Name="SliderProcessing" Maximum="100" HorizontalAlignment="Stretch"/> </Grid> <StackPanel Orientation="Horizontal" HorizontalAlignment="Center"> <Button x:Name="ButtonStart" Click="ButtonStart_Click" Content="Start" Margin="5 0"/> <Button x:Name="ButtonPause" Click="ButtonPause_Click" Content="Pause" Margin="5 0"/> </StackPanel> </StackPanel> </Border> <!-- System.Windows.Threading.DispatcherTimer UI --> <Border Width="200" Height="200" BorderBrush="Black" BorderThickness="1"> <StackPanel > <TextBlock FontSize="14" TextWrapping="Wrap" FontWeight="DemiBold" Text="System.Windows.Threading.DispatcherTimer" Margin="5 10"/> <Grid Margin="5 10"> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <TextBlock Text="进度:" VerticalAlignment="Center"/> <Slider Grid.Column="1" x:Name="SliderDispatcherProcessing" Maximum="100" HorizontalAlignment="Stretch"/> </Grid> <StackPanel Orientation="Horizontal" HorizontalAlignment="Center"> <Button x:Name="ButtonDispatcherStart" Click="ButtonDispatcherStart_Click" Content="Start" Margin="5 0"/> <Button x:Name="ButtonDispatcherPause" Click="ButtonDispatcherPause_Click" Content="Pause" Margin="5 0"/> </StackPanel> </StackPanel> </Border> </WrapPanel> </Grid> </Window>
-
定时器的使用和控制
using System; using System.Threading; using System.Windows; namespace Melphi { /// <summary> /// MainWindow.xaml 的交互逻辑 /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); InitializeWindowsDispatcherTimer(); } /// <summary> /// System.Windows.Threading.DispatcherTimer 实例, /// 不推荐使用的定时器 /// </summary> private System.Windows.Threading.DispatcherTimer mWindowsDispatcherTimer; /// <summary> /// 初始化 System.Windows.Threading.DispatcherTimer 定时器 /// </summary> private void InitializeWindowsDispatcherTimer() { // 初始化一个定时器,时间间隔为500ms mWindowsDispatcherTimer = new System.Windows.Threading.DispatcherTimer() { Interval = new TimeSpan(0, 0, 0, 0, 500) }; // 设置定时器间隔发生的处理事件( mWindowsDispatcherTimer.Tick += MWindowsDispatcherTimer_Tick; } /// <summary> /// 超过计时器间隔,这个方法会被执行一次,在UI线程中执行 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void MWindowsDispatcherTimer_Tick(object sender, EventArgs e) { // TODO // 直接刷新 UI 元素 SliderDispatcherProcessing.Value += 5; } /// <summary> /// 启动定时器 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void ButtonDispatcherStart_Click(object sender, RoutedEventArgs e) { mWindowsDispatcherTimer.Start(); } /// <summary> /// 停止定时器 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void ButtonDispatcherPause_Click(object sender, RoutedEventArgs e) { mWindowsDispatcherTimer.Stop(); } } }
-
效果
总结
直接设置时间间隔,具有Start
与Stop
等控制方法。可以直接操作UI线程创建的对象。
System.Windows.Forms.Timer
简介
这是 Winform 平台特有的定时器,该定时器的工作原理和System.Windows.Threading.DispatcherTimer相同,针对的平台是Winform。优缺点相同。
使用
-
UI设计
-
定时器的使用和控制
using System; using System.Windows.Forms; namespace Melphi.Winform { public partial class Form1 : Form { public Form1() { InitializeComponent(); InitializeWindowsFromsTimer(); } /// <summary> /// System.Windows.Forms.Timer 实例 /// </summary> System.Windows.Forms.Timer mWindowsFromsTimer; /// <summary> /// 初始化 System.Windows.Forms.Timer 定时器 /// </summary> private void InitializeWindowsFromsTimer() { // 初始化一个定时器,时间间隔为500ms mWindowsFromsTimer = new System.Windows.Forms.Timer() { Interval= 500, }; // 设置定时器间隔发生的处理事件( mWindowsFromsTimer.Tick += MWindowsFromsTimer_Tick; } /// <summary> /// 超过计时器间隔,这个方法会被执行一次,在UI线程中执行 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void MWindowsFromsTimer_Tick(object sender, EventArgs e) { // TODO // 直接控制UI控件 progressBar1.Value += 2; } /// <summary> /// 启动定时器 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void ButtonStart_Click(object sender, EventArgs e) { mWindowsFromsTimer.Start(); } /// <summary> /// 停止定时器 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void ButtonStop_Click(object sender, EventArgs e) { mWindowsFromsTimer.Stop(); } } }
-
效果
总结
和WPF的DispatcherTimer
非常相似,用法和功能上,因为调度是UI线程来完成,因此都能直接控制UI控件。
System.UI.Xaml. DispatcherTimer
简介
这是 Window Store 平台特有的定时器,该定时器的工作原理和System.Windows.Threading.DispatcherTimer相同,针对的平台是 Window Store。优缺点相同。
使用
和前面的使用差不多,这里就不在多做描述了,请读者自行完成。
Over
每次记录一小步…点点滴滴人生路…