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 线程。
相关推荐
SmartRadio2 小时前
计算 CH584M-SX1262-W25Q16 组合最低功耗 (1)
c语言·开发语言·物联网·lora·lorawan
bosins2 小时前
基于Python实现PDF文件个人隐私信息检查
开发语言·python·pdf
bosins2 小时前
基于Python开发PDF文件元数据查看器
开发语言·python·pdf
小北方城市网2 小时前
第 10 课:Python 全体系实战整合与职业进阶指南(完结篇)
大数据·开发语言·数据库·python
Ghost-Silver2 小时前
2025年度总结
开发语言·数据结构·c++·算法
The star"'2 小时前
Python
开发语言·python·pygame
秋雨雁南飞2 小时前
C# 动态脚本执行器
c#·动态编译
superman超哥2 小时前
Rust Link-Time Optimization (LTO):跨边界的全局优化艺术
开发语言·后端·rust·lto·link-time·跨边界·优化艺术
superman超哥2 小时前
Rust 编译优化选项配置:释放性能潜力的精细调控
开发语言·后端·rust·rust编译优化·精细调控·编译优化选项