C# 中常用的定时器主要有 4 种,分别适用于不同场景,下面我将逐一详细介绍它们的语法、使用示例及核心特性。一、System.Threading.Timer(线程池定时器,无 UI 绑定)
这是一个轻量级定时器,基于线程池线程执行回调,不依赖 UI 线程,适用于后台任务、非 UI 场景。
核心语法
public Timer(TimerCallback callback, object? state, TimeSpan dueTime, TimeSpan period);public Timer(TimerCallback callback, object? state, int dueTime, int period);
Change(TimeSpan dueTime, TimeSpan period)Dispose()
使用示例
using System;using System.Threading;class ThreadingTimerDemo{ static void Main() { var timerState = new { TimerName = "后台任务定时器", Count = 0 }; using (var timer = new Timer(TimerCallback, timerState, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(2))) { Console.WriteLine("定时器已启动,按任意键停止..."); Console.ReadKey(); } } private static void TimerCallback(object? state) { if (state is not { } timerState) return; dynamic stateObj = timerState; stateObj.Count++; Console.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss} - {stateObj.TimerName},触发次数:{stateObj.Count}"); }}
二、System.Timers.Timer(基于组件的定时器,支持事件)
这是一个组件化定时器,封装了System.Threading.Timer,提供事件驱动模型,支持自动重置,同样基于线程池线程执行,适用于后台业务逻辑。
核心语法
IntervalEnabled:是否启用定时器(true启用,false禁用,也可使用Start()/Stop()方法)AutoReset:是否自动重复触发(默认true,设为false则仅触发一次)
Elapsed:定时器触发时触发的事件(事件处理方法签名:void 方法名(object sender, ElapsedEventArgs e))
Start():启用定时器(等价于Enabled = true)Stop():禁用定时器(等价于Enabled = false)Dispose()
使用示例
using System;using System.Timers;class TimersTimerDemo{ static int triggerCount = 0; static void Main() { var timer = new System.Timers.Timer(); timer.Interval = 2000; timer.AutoReset = true; timer.Enabled = true; timer.Elapsed += Timer_Elapsed; Console.WriteLine("Timers定时器已启动,按任意键停止..."); Console.ReadKey(); timer.Stop(); timer.Dispose(); } private static void Timer_Elapsed(object? sender, ElapsedEventArgs e) { triggerCount++; Console.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss} - Timers定时器触发,次数:{triggerCount}"); }}
三、System.Windows.Forms.Timer(WinForm UI 定时器)
该定时器依赖 WinForm 消息循环,运行在 UI 线程上,不会造成跨线程问题,适用于更新 UI 控件(如进度条、倒计时)。
核心语法
IntervalEnabled:是否启用定时器(true/false,对应Start()/Stop())
Tick:定时器触发时的事件(UI 线程执行,可直接操作 UI 控件)
使用示例(WinForm 项目中)
using System;using System.Windows.Forms;namespace WinFormTimerDemo{ public partial class Form1 : Form { int count = 0; public Form1() { InitializeComponent(); var uiTimer = new System.Windows.Forms.Timer(); uiTimer.Interval = 1000; uiTimer.Tick += UiTimer_Tick; Button btnStart = new Button { Text = "启动定时器", Location = new System.Drawing.Point(10, 10) }; Button btnStop = new Button { Text = "停止定时器", Location = new System.Drawing.Point(120, 10) }; Label lblCount = new Label { Location = new System.Drawing.Point(10, 50), Width = 200 }; btnStart.Click += (s, e) => uiTimer.Start(); btnStop.Click += (s, e) => uiTimer.Stop(); this.Controls.Add(btnStart); this.Controls.Add(btnStop); this.Controls.Add(lblCount); void UiTimer_Tick(object? sender, EventArgs e) { count++; lblCount.Text = $"UI定时器触发次数:{count},当前时间:{DateTime.Now:HH:mm:ss}"; } } }}
四、System.Windows.Threading.DispatcherTimer(WPF/UI 线程定时器)
该定时器是 WPF 专属,绑定 UI 线程的 Dispatcher(消息调度器),运行在 UI 线程上,可安全操作 WPF UI 控件,支持优先级设置。
核心语法
IntervalIsEnabled:是否启用定时器(true/false,对应Start()/Stop())Priority:定时器执行优先级(基于 Dispatcher 优先级,默认DispatcherPriority.Normal)
使用示例(WPF 项目中)
using System;using System.Windows;using System.Windows.Threading;namespace WpfDispatcherTimerDemo{ public partial class MainWindow : Window { int tickCount = 0; private DispatcherTimer _dispatcherTimer; public MainWindow() { InitializeComponent(); _dispatcherTimer = new DispatcherTimer(); _dispatcherTimer.Interval = TimeSpan.FromSeconds(1); _dispatcherTimer.Priority = DispatcherPriority.Normal; _dispatcherTimer.Tick += DispatcherTimer_Tick; var btnStart = new System.Windows.Controls.Button { Content = "启动定时器", Margin = new Thickness(10) }; var btnStop = new System.Windows.Controls.Button { Content = "停止定时器", Margin = new Thickness(10) }; var txtCount = new System.Windows.Controls.TextBlock { Margin = new Thickness(10) }; btnStart.Click += (s, e) => _dispatcherTimer.Start(); btnStop.Click += (s, e) => _dispatcherTimer.Stop(); var stackPanel = new System.Windows.Controls.StackPanel { Orientation = System.Windows.Controls.Orientation.Vertical }; stackPanel.Children.Add(btnStart); stackPanel.Children.Add(btnStop); stackPanel.Children.Add(txtCount); this.Content = stackPanel; void DispatcherTimer_Tick(object? sender, EventArgs e) { tickCount++; txtCount.Text = $"Dispatcher定时器触发次数:{tickCount},当前时间:{DateTime.Now:HH:mm:ss}"; } } }}
五、四种定时器核心区别总结
| | | |
|---|
System.Threading.Timer | | | |
System.Timers.Timer | | | |
Windows.Forms.Timer | | | |
DispatcherTimer | | | 绑定 Dispatcher、支持优先级、安全操作 UI |
关键注意事项
- 线程安全:
Threading.Timer和Timers.Timer运行在线程池线程,操作共享资源时需使用lock等同步机制; - 资源释放:前两种定时器需手动调用
Dispose()释放资源,推荐使用using语句; - 精度:UI 定时器(Forms/Dispatcher)精度较低(依赖消息循环),后台定时器精度更高;
- 跨线程问题:后台定时器不可直接操作 UI 控件,需通过
Control.Invoke(WinForm)或Dispatcher.Invoke(WPF)切换到 UI 线程。
阅读原文:原文链接
该文章在 2026/1/19 10:33:30 编辑过