0

0

c# 如何实现一个定时任务

煙雲

煙雲

发布时间:2026-01-08 10:29:02

|

942人浏览过

|

来源于php中文网

原创

System.Threading.Timer适合轻量级单机定时任务,IHostedService适用于.NET Core后台服务,超出现有能力时应升级为Windows服务、Quartz.NET或系统计划任务。

c# 如何实现一个定时任务

System.Threading.Timer 实现轻量级定时任务

适合单次延迟执行、周期性简单操作(比如每 5 秒检查一次状态),不依赖外部服务,也不需要持久化或跨进程调度。

它在后台线程池中运行,不会阻塞主线程,但要注意:回调函数里不能直接更新 UI(WinForms/WPF 需用 Invoke);如果回调抛出未捕获异常,整个 Timer 会静默停止。

  • dueTime 是首次触发前的毫秒延迟(TimeSpan.Zero 表示立即执行)
  • period 是后续重复间隔(设为 Timeout.Infinite 就只执行一次)
  • 务必保存对 Timer 实例的引用,否则可能被 GC 回收导致任务意外终止
private Timer _timer;

public void StartCheck() { timer = new Timer( => { Console.WriteLine($"Tick at {DateTime.Now:HH:mm:ss}"); // 注意:这里不能直接调用 WinForms 的 this.Text = ... }, null, TimeSpan.Zero, TimeSpan.FromSeconds(5)); }

Microsoft.Extensions.Hosting.IHostedService 做后台服务级定时任务

适用于 .NET Core / .NET 5+ 的 Web API 或后台服务项目,配合 DI 容器管理生命周期,支持优雅关闭(比如正在执行的任务可等待完成)。

比裸用 Timer 更健壮,但引入了依赖注入和宿主生命周期概念——如果你没在用 WebHostHostBuilder,这条路走不通。

  • 必须实现 StartAsyncStopAsync
  • StartAsync 中启动 Timer,并在 StopAsync 中调用 _timer?.Change(Timeout.Infinite, 0) 停止它
  • 别在 StopAsync 里用 await _timer?.DisposeAsync() —— Timer 不支持异步释放
public class CheckStatusService : IHostedService, IDisposable
{
    private Timer _timer;
public Task StartAsync(CancellationToken cancellationToken)
{
    _timer = new Timer(DoWork, null, TimeSpan.Zero, TimeSpan.FromMinutes(1));
    return Task.CompletedTask;
}

private void DoWork(object state) => Console.WriteLine("Checking...");

public Task StopAsync(CancellationToken cancellationToken)
{
    _timer?.Change(Timeout.Infinite, 0);
    return Task.CompletedTask;
}

public void Dispose() => _timer?.Dispose();

}

网奇英文商城外贸系统
网奇英文商城外贸系统

网奇Eshop是一个带有国际化语言支持的系统,可以同时在一个页面上显示全球任何一种语言而没有任何障碍、任何乱码。在本系统中您可以发现,后台可以用任意一种语言对前台进行管理、录入而没有阻碍。而任何一个国家的浏览者也可以用他们的本国语言在你的网站上下订单、留言。用户可以通过后台随意设定软件语言,也就是说你可以用本软件开设简体中文、繁体中文与英文或者其他语言的网上商店。网奇Eshop系统全部版本都使用模

下载

遇到 ObjectDisposedException 或任务突然不执行?检查这几点

这是最常踩的坑:任务看似启动了,跑几次就停,或者一关程序就报 Cannot access a disposed object

  • 确认 Timer 实例是类字段(private Timer _timer),不是局部变量
  • 确认没有在回调里调用了 _timer.Dispose()_timer?.Dispose() —— 这会导致后续触发失败
  • 如果用了 IHostedService,确保已通过 services.AddHostedService() 注册
  • 在 ASP.NET Core 中,不要在 Controller 里 new 一个 Timer —— Controller 实例生命周期短,Timer 很快被回收

什么时候该换方案?

当需求超出内存内定时能力时,就得换路子:

  • 需要机器重启后继续运行 → 用 Windows 服务 + System.ServiceProcess.ServiceBase,或 Linux systemd service
  • 要支持失败重试、依赖其他任务、可视化监控 → 上 Quartz.NET(注意它默认不持久化,加 AdoJobStore 才能存 DB)
  • 部署在多台服务器,但同一任务只能跑一次 → 需分布式锁(如 Redis + RedLock)或 Quartz 的集群模式
  • 只是每天凌晨跑个导出 → 直接用系统级计划任务(Windows Task Scheduler / Linux cron),C# 程序做成命令行工具即可

真正难的不是“怎么让代码隔段时间跑一次”,而是“怎么保证它在各种异常下依然可靠、可观测、可维护”。选最简单的方案起步,等痛点出现再升级。

相关专题

更多
什么是分布式
什么是分布式

分布式是一种计算和数据处理的方式,将计算任务或数据分散到多个计算机或节点中进行处理。本专题为大家提供分布式相关的文章、下载、课程内容,供大家免费下载体验。

321

2023.08.11

分布式和微服务的区别
分布式和微服务的区别

分布式和微服务的区别在定义和概念、设计思想、粒度和复杂性、服务边界和自治性、技术栈和部署方式等。本专题为大家提供分布式和微服务相关的文章、下载、课程内容,供大家免费下载体验。

231

2023.10.07

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

476

2023.08.10

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

476

2023.08.10

windows查看端口占用情况
windows查看端口占用情况

Windows端口可以认为是计算机与外界通讯交流的出入口。逻辑意义上的端口一般是指TCP/IP协议中的端口,端口号的范围从0到65535,比如用于浏览网页服务的80端口,用于FTP服务的21端口等等。怎么查看windows端口占用情况呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

564

2023.07.26

查看端口占用情况windows
查看端口占用情况windows

端口占用是指与端口关联的软件占用端口而使得其他应用程序无法使用这些端口,端口占用问题是计算机系统编程领域的一个常见问题,端口占用的根本原因可能是操作系统的一些错误,服务器也可能会出现端口占用问题。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

1083

2023.07.27

windows照片无法显示
windows照片无法显示

当我们尝试打开一张图片时,可能会出现一个错误提示,提示说"Windows照片查看器无法显示此图片,因为计算机上的可用内存不足",本专题为大家提供windows照片无法显示相关的文章,帮助大家解决该问题。

775

2023.08.01

windows查看端口被占用的情况
windows查看端口被占用的情况

windows查看端口被占用的情况的方法:1、使用Windows自带的资源监视器;2、使用命令提示符查看端口信息;3、使用任务管理器查看占用端口的进程。本专题为大家提供windows查看端口被占用的情况的相关的文章、下载、课程内容,供大家免费下载体验。

446

2023.08.02

java学习网站推荐汇总
java学习网站推荐汇总

本专题整合了java学习网站相关内容,阅读专题下面的文章了解更多详细内容。

33

2026.01.08

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL 教程
PostgreSQL 教程

共48课时 | 6.8万人学习

Git 教程
Git 教程

共21课时 | 2.5万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号