C# 中常用的定时器详解

C# 中常用的定时器主要有 4 种,分别适用于不同场景,下面我将逐一详细介绍它们的语法、使用示例及核心特性:

一、System.Threading.Timer(线程池定时器,无 UI 绑定)

这是一个轻量级定时器,基于线程池线程执行回调,不依赖 UI 线程,适用于后台任务、非 UI 场景。

核心语法
  1. 构造函数(常用重载):

    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);
  2. 关键方法:

    • 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提供事件驱动模型,支持自动重置,同样基于线程池线程执行,适用于后台业务逻辑。

核心语法
  1. 核心属性:
    • Interval:触发间隔(毫秒数,默认 100 毫秒)
    • Enabled:是否启用定时器(true启用,false禁用,也可使用Start()/Stop()方法)
    • AutoReset:是否自动重复触发(默认true,设为false则仅触发一次)
  2. 核心事件:
    • Elapsed:定时器触发时触发的事件(事件处理方法签名:void 方法名(object sender, ElapsedEventArgs e)
  3. 关键方法:
    • 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 控件(如进度条、倒计时)。

核心语法
  1. 核心属性:
    • Interval:触发间隔(毫秒数)
    • Enabled:是否启用定时器(true/false,对应Start()/Stop()
  2. 核心事件:
    • Tick:定时器触发时的事件(UI 线程执行,可直接操作 UI 控件)
  3. 关键方法:
    • 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 控件,支持优先级设置。

核心语法
  1. 核心属性:
    • Interval:触发间隔(TimeSpan类型,推荐使用)
    • IsEnabled:是否启用定时器(true/false,对应Start()/Stop()
    • Priority:定时器执行优先级(基于 Dispatcher 优先级,默认DispatcherPriority.Normal
  2. 核心事件:
    • Tick:定时器触发事件(UI 线程执行,无跨线程问题)
  3. 关键方法:
    • 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

关键注意事项

  1. 线程安全:Threading.TimerTimers.Timer运行在线程池线程,操作共享资源时需使用lock等同步机制;
  2. 资源释放:前两种定时器需手动调用Dispose()释放资源,推荐使用using语句;
  3. 精度:UI 定时器(Forms/Dispatcher)精度较低(依赖消息循环),后台定时器精度更高;
  4. 跨线程问题:后台定时器不可直接操作 UI 控件,需通过Control.Invoke(WinForm)或Dispatcher.Invoke(WPF)切换到 UI 线程。
相关推荐
MinterFusion6 小时前
Java后端高频术语表
java·开发语言·后端·程序员·大厂面试·术语
sycmancia6 小时前
Qt——计算器示例(用户界面与业务逻辑的分离)
开发语言·qt·ui
专注VB编程开发20年6 小时前
delphi死嗑Pascal冷门编程语言,Borland不认可 “通用多语言 IDE”,认为 “专有语言才是护城河”
开发语言·ide·delphi
hzxpaipai6 小时前
外贸网站制作:为何派迪科技做的网站性能与打开速度如此不错?
开发语言·前端·网络·科技·安全
于先生吖6 小时前
高并发稳定运营,JAVA 动漫短剧小程序 + H5 源码
java·开发语言·小程序
青桔柠薯片6 小时前
I²C 总线协议学习总结:从开漏逻辑到读写事务的工程视角
c语言·开发语言·学习
2401_827499996 小时前
python核心语法04-函数
开发语言·python
重生之我是Java开发战士6 小时前
【笔试强训】Week1:点击消除,数组中两个字符串的最小距离,dd爱框框,腐烂的苹果,大数乘法
java·开发语言·算法
独特的螺狮粉6 小时前
开源鸿蒙跨平台Flutter开发:地震震源探测系统-地震波形与波干涉渲染架构
开发语言·flutter·华为·架构·开源·harmonyos
牧瀬クリスだ6 小时前
优先级队列——堆
java·开发语言·数据结构