C# 定时器实现

在C#中,实现定时器功能有多种方式,下面将介绍最常用的几种定时器实现方法,包括它们的特性、适用场景和示例代码。

实现方法

Timers.Timer

这是最常用的定时器,适用于需要在特定时间间隔触发事件的场景。

优点:

  • 使用方便

  • 基于线程池工作

  • 可以设置AutoReset属性控制是否自动重复

缺点

  • 精度有限,约为10-20毫秒

  • 如果事件处理时间超过间隔,可能导致事件堆积

适用场景

  • 后台服务

  • 服务器应用程序

  • 需要定期执行但不要求高精度的任务

cs 复制代码
using System;
using System.Timers;

public class TimerExample
{
    private static Timer timer;
    
    public static void Main()
    {
        // 创建定时器,间隔1000毫秒(1秒)
        timer = new Timer(1000);
        
        // 绑定Elapsed事件
        timer.Elapsed += OnTimedEvent;
        
        // 设置定时器自动重置(默认为true)
        timer.AutoReset = true;
        
        // 启用定时器
        timer.Enabled = true;
        
        Console.WriteLine("按任意键退出...");
        Console.ReadKey();
        
        // 停止定时器
        timer.Stop();
        timer.Dispose();
    }
    
    private static void OnTimedEvent(object source, ElapsedEventArgs e)
    {
        Console.WriteLine($"定时事件触发于: {e.SignalTime:HH:mm:ss.fff}");
    }
}

Threading.Timer

轻量级的线程池定时器,适合需要高性能的场景。

优点

  • 最轻量级的定时器

  • 直接使用线程池

  • 性能最好

  • 可以动态更改间隔时间

缺点

  • 只有回调没有事件,使用稍复杂

  • 回调中异常会导致整个应用程序崩溃

适用场景

  • 高性能后台任务

  • 需要频繁创建/销毁定时器的场景

cs 复制代码
using System;
using System.Threading;

public class ThreadingTimerExample
{
    private static Timer timer;
    
    public static void Main()
    {
        // 创建定时器:第一个参数是回调方法,第二个是状态对象,
        // 第三个是延迟时间(毫秒),第四个是间隔时间(毫秒)
        timer = new Timer(TimerCallback, null, 0, 1000);
        
        Console.WriteLine("按任意键退出...");
        Console.ReadKey();
        
        // 释放定时器资源
        timer.Dispose();
    }
    
    private static void TimerCallback(object state)
    {
        Console.WriteLine($"定时回调触发于: {DateTime.Now:HH:mm:ss.fff}");
    }
}

Diagnostics.Stopwatch + 异步循环

优点

  • 可实现最高精度

  • 完全控制执行流程

  • 可适应复杂调度需求

缺点

  • 实现较复杂

  • 需要手动处理各种边界情况

适用场景

  • 游戏循环

  • 多媒体处理

  • 需要精确时间控制的场景

cs 复制代码
using System;
using System.Diagnostics;
using System.Threading.Tasks;

public class HighPrecisionTimer
{
    public static async Task Start(int intervalMs, Action action, CancellationToken cancellationToken)
    {
        var stopwatch = new Stopwatch();
        stopwatch.Start();
        
        long nextTrigger = 0;
        
        while (!cancellationToken.IsCancellationRequested)
        {
            long elapsed = stopwatch.ElapsedMilliseconds;
            
            if (elapsed >= nextTrigger)
            {
                action();
                nextTrigger = elapsed + intervalMs;
            }
            
            // 减少CPU占用
            await Task.Delay(1, cancellationToken);
        }
    }
    
    public static async Task Main()
    {
        var cts = new CancellationTokenSource();
        
        Console.WriteLine("按任意键停止...");
        
        // 启动高精度定时器,每100毫秒执行一次
        var timerTask = Start(100, () => {
            Console.WriteLine($"高精度定时器触发: {DateTime.Now:HH:mm:ss.fff}");
        }, cts.Token);
        
        Console.ReadKey();
        cts.Cancel();
        
        try { await timerTask; } catch (TaskCanceledException) {}
    }
}

PeriodicTimer

.NET 6引入的新定时器,专为异步场景设计。

优点

  • 专为异步设计

  • 使用简单直观

  • 与CancellationToken集成良好

缺点

适用场景

  • 现代异步应用程序

  • 需要与其他异步操作集成的定时任务

cs 复制代码
using System;
using System.Threading;
using System.Threading.Tasks;

public class PeriodicTimerExample
{
    public static async Task Main()
    {
        using var timer = new PeriodicTimer(TimeSpan.FromSeconds(1));
        
        while (await timer.WaitForNextTickAsync())
        {
            Console.WriteLine($"PeriodicTimer触发于: {DateTime.Now:HH:mm:ss.fff}");
        }
    }
}

Windows.Forms.Timer

Windows窗体应用程序专用的定时器,事件在UI线程上执行。

优点

  • 专门用于Windows窗体应用

  • Tick事件在UI线程执行,可直接操作UI控件

  • 使用简单

缺点

  • 精度最低(约55ms)

  • 如果Tick处理耗时会导致UI卡顿

适用场景

  • Windows窗体应用程序

  • 需要更新UI的定时操作

cs 复制代码
using System;
using System.Windows.Forms;

public class FormsTimerExample : Form
{
    private Timer timer;
    
    public FormsTimerExample()
    {
        timer = new Timer();
        timer.Interval = 1000; // 1秒
        timer.Tick += Timer_Tick;
        timer.Start();
    }
    
    private void Timer_Tick(object sender, EventArgs e)
    {
        Console.WriteLine($"窗体定时器触发于: {DateTime.Now:HH:mm:ss.fff}");
    }
    
    [STAThread]
    public static void Main()
    {
        Application.Run(new FormsTimerExample());
    }
}

对比

定时器类型 精度 线程模型 适用场景
System.Timers.Timer 中等(10~20ms) 线程池 服务器应用、后台服务
System.Threading.Timer 中等(10~20ms) 线程池 高性能需求、后台任务
System.Windows.Forms.Timer 低(~55ms) UI线程 Windows窗体应用
Stopwatch+异步循环 高(1ms) 自定义 游戏、多媒体、高精度需求
PeriodicTimer (.NET 6+) 中等 异步 现代异步应用

选择定时器时应考虑以下因素:

  1. 执行环境

    • Windows窗体应用 → System.Windows.Forms.Timer

    • WPF应用 → DispatcherTimer

    • 控制台/服务 → System.Timers.Timer 或 System.Threading.Timer

    • 现代异步应用 → PeriodicTimer

  2. 精度需求

    • 普通需求(秒级):任意定时器

    • 中等需求(10-50ms):System.Timers.Timer 或 System.Threading.Timer

    • 高精度需求(1ms):Stopwatch+异步循环

  3. 线程要求

    • 需要更新UI → UI线程定时器(Forms.Timer/DispatcherTimer)

    • 后台执行 → 线程池定时器(Timers.Timer/Threading.Timer)

  4. .NET版本

    • .NET 6+ → 优先考虑PeriodicTimer

    • 旧版本 → 选择其他适合的定时器

  5. 功能需求

    • 需要动态调整间隔 → System.Threading.Timer

    • 需要简单事件模型 → System.Timers.Timer

    • 需要复杂调度逻辑 → Stopwatch+自定义循环

相关推荐
心疼你的一切10 分钟前
使用Unity引擎开发Rokid主机应用的全面配置交互操作
学习·游戏·unity·c#·游戏引擎·交互
椒颜皮皮虾྅7 小时前
【DeploySharp 】基于DeploySharp 的深度学习模型部署测试平台:安装和使用流程
人工智能·深度学习·开源·c#·openvino
kalvin_y_liu13 小时前
【MES架构师与C#高级工程师(设备控制方向)两大职业路径的技术】
开发语言·职场和发展·c#·mes
椒颜皮皮虾15 小时前
基于DeploySharp 的深度学习模型部署测试平台:支持YOLO全系列模型
c#
李宥小哥1 天前
C#基础10-结构体和枚举
java·开发语言·c#
secondyoung3 天前
Markdown转换为Word:Pandoc模板使用指南
开发语言·经验分享·笔记·c#·编辑器·word·markdown
andyguo3 天前
AI模型测评平台工程化实战十二讲(第五讲:大模型测评分享功能:安全、高效的结果展示与协作)
人工智能·安全·c#
大飞pkz3 天前
【设计模式】访问者模式
开发语言·设计模式·c#·访问者模式
LateFrames3 天前
用 【C# + Winform + MediaPipe】 实现人脸468点识别
python·c#·.net·mediapipe
R-G-B4 天前
【14】C#实战篇——C++动态库dll 接口函数将char* strErr字符串 传给C# ,并且在winform的MessageBox和listbox中显示。C++ string 日志传给 C#
c++·c#·strerr字符串传给c#·动态库dll传递字符串给c#·string日志传给c#·c++ string传给 c#·c++底层函数日志传给c#显示