C# 中常用的定时器主要有 4 种,分别适用于不同场景,下面我将逐一详细介绍它们的语法、使用示例及核心特性:
一、System.Threading.Timer(线程池定时器,无 UI 绑定)
这是一个轻量级定时器,基于线程池线程执行回调,不依赖 UI 线程,适用于后台任务、非 UI 场景。
核心语法
-
构造函数(常用重载):
cs// 参数说明: // callback:定时器触发时执行的回调方法(TimerCallback委托,接收object类型参数) // state:传递给回调方法的自定义参数(可设为null) // dueTime:首次触发延迟时间(TimeSpan或毫秒数,Timeout.Infinite表示永不首次触发) // period:后续触发的时间间隔(TimeSpan或毫秒数,Timeout.Infinite表示仅触发一次) 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语句管理)
使用示例
cs
using System;
using System.Threading;
class ThreadingTimerDemo
{
static void Main()
{
// 定义自定义状态参数
var timerState = new { TimerName = "后台任务定时器", Count = 0 };
// 创建定时器:首次延迟1秒,之后每2秒触发一次
using (var timer = new Timer(TimerCallback, timerState, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(2)))
{
Console.WriteLine("定时器已启动,按任意键停止...");
Console.ReadKey(); // 阻塞主线程,防止程序退出
}
}
// 定时器回调方法(必须匹配TimerCallback委托签名)
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,提供事件驱动模型,支持自动重置,同样基于线程池线程执行,适用于后台业务逻辑。
核心语法
- 核心属性:
Interval:触发间隔(毫秒数,默认 100 毫秒)Enabled:是否启用定时器(true启用,false禁用,也可使用Start()/Stop()方法)AutoReset:是否自动重复触发(默认true,设为false则仅触发一次)
- 核心事件:
Elapsed:定时器触发时触发的事件(事件处理方法签名:void 方法名(object sender, ElapsedEventArgs e))
- 关键方法:
Start():启用定时器(等价于Enabled = true)Stop():禁用定时器(等价于Enabled = false)Dispose():释放资源
使用示例
cs
using System;
using System.Timers;
class TimersTimerDemo
{
static int triggerCount = 0; // 记录触发次数
static void Main()
{
// 创建定时器
var timer = new System.Timers.Timer();
// 设置属性
timer.Interval = 2000; // 间隔2秒
timer.AutoReset = true; // 自动重复触发
timer.Enabled = true; // 启用定时器
// 绑定Elapsed事件
timer.Elapsed += Timer_Elapsed;
Console.WriteLine("Timers定时器已启动,按任意键停止...");
Console.ReadKey();
// 停止并释放定时器
timer.Stop();
timer.Dispose();
}
// Elapsed事件处理方法
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 控件(如进度条、倒计时)。
核心语法
- 核心属性:
Interval:触发间隔(毫秒数)Enabled:是否启用定时器(true/false,对应Start()/Stop())
- 核心事件:
Tick:定时器触发时的事件(UI 线程执行,可直接操作 UI 控件)
- 关键方法:
Start():启用定时器Stop():禁用定时器
使用示例(WinForm 项目中)
cs
using System;
using System.Windows.Forms;
namespace WinFormTimerDemo
{
public partial class Form1 : Form
{
int count = 0;
public Form1()
{
InitializeComponent();
// 1. 手动创建定时器(或通过控件面板拖拽)
var uiTimer = new System.Windows.Forms.Timer();
uiTimer.Interval = 1000; // 1秒间隔
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);
// Tick事件更新UI
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 控件,支持优先级设置。
核心语法
- 核心属性:
Interval:触发间隔(TimeSpan类型,推荐使用)IsEnabled:是否启用定时器(true/false,对应Start()/Stop())Priority:定时器执行优先级(基于 Dispatcher 优先级,默认DispatcherPriority.Normal)
- 核心事件:
Tick:定时器触发事件(UI 线程执行,无跨线程问题)
- 关键方法:
Start():启用定时器Stop():禁用定时器
使用示例(WPF 项目中)
cs
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
_dispatcherTimer = new DispatcherTimer();
_dispatcherTimer.Interval = TimeSpan.FromSeconds(1); // 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;
// Tick事件更新WPF UI
void DispatcherTimer_Tick(object? sender, EventArgs e)
{
tickCount++;
txtCount.Text = $"Dispatcher定时器触发次数:{tickCount},当前时间:{DateTime.Now:HH:mm:ss}";
}
}
}
}
五、四种定时器核心区别总结
| 定时器类型 | 执行线程 | 适用场景 | 核心特点 |
|---|---|---|---|
System.Threading.Timer |
线程池线程 | 后台非 UI 任务、轻量级操作 | 轻量、高效、无事件模型、需手动处理线程安全 |
System.Timers.Timer |
线程池线程 | 后台业务逻辑、非 UI 场景 | 事件驱动、支持自动重置、封装更友好 |
Windows.Forms.Timer |
WinForm UI 线程 | WinForm 界面更新(进度条等) | 无跨线程问题、依赖消息循环、精度较低 |
DispatcherTimer |
WPF UI 线程 | WPF 界面更新、UI 交互任务 | 绑定 Dispatcher、支持优先级、安全操作 UI |
关键注意事项
- 线程安全:
Threading.Timer和Timers.Timer运行在线程池线程,操作共享资源时需使用lock等同步机制; - 资源释放:前两种定时器需手动调用
Dispose()释放资源,推荐使用using语句; - 精度:UI 定时器(Forms/Dispatcher)精度较低(依赖消息循环),后台定时器精度更高;
- 跨线程问题:后台定时器不可直接操作 UI 控件,需通过
Control.Invoke(WinForm)或Dispatcher.Invoke(WPF)切换到 UI 线程。