介绍
定时任务又称“计划任务”,是指在预定的时间点或周期自动触发并执行的一段业务逻辑。它把“人工操作”变为“系统自动完成”。
System.Threading.Timer 是 .NET 里最轻量的后台定时器,主要有三个特点:
- 在指定毫秒后第一次触发回调;
- 之后按固定间隔重复(可设为
Timeout.Infinite只跑一次); - 全程由线程池线程执行,不占用 UI 线程。
核心构造
new Timer(TimerCallback callback, object state, int dueTime, int period)
dueTime:首次延迟(毫秒);-1表示永不动;0立即执行。period:后续间隔;-1表示只跑一次。state:回调参数
常用方法:
Change(due, period):随时“改表”,重置触发计划。Dispose():释放资源,停表。
适用版本
.NET Core 3.1 及以上版本
实现方法
通过.NET Core 自带的定时任务框架实现,分为以下几步:
1.实现 IHostedService 接口
IHostedService 接口提供了两个方法:StartAsync 和 StopAsync,用于控制后台任务的启动和停止。创建一个类来实现这个接口,并在 StartAsync 方法中配置定时任务。
2.示例代码
该代码实现了一个“定时器”:每天24点触发一次DailyMethod,这个方法里定义业务逻辑。执行完后再把下一次预约到隔天24:00,如此循环,每天零点自动执行一次业务代码。
public Task StartAsync(CancellationToken cancellationToken)
{
// 计算距离“明天 00:00”还有多少毫秒
var now = DateTime.Now;
var next = now.Date.AddDays(1);
var due = (int)Math.Min(
Math.Max(0, (next - now).TotalMilliseconds),
int.MaxValue);
// 24 小时循环
_timer = new Timer(DoWork, null, due, Timeout.Infinite);
return Task.CompletedTask;
}
private void DoWork(object state)
{
try
{
DailyMethod();
}
catch (Exception ex)
{
Logger.Info(ex.ToString());
}
finally
{
// 重新设定到明天 00:00
var next = DateTime.Now.Date.AddDays(1); // 明天 0 点
var due = (int)Math.Max(0, (next - DateTime.Now).TotalMilliseconds);
_timer?.Change(due, Timeout.Infinite);
}
}
public Task StopAsync(CancellationToken cancellationToken)
{
_timer?.Change(Timeout.Infinite, 0);
return Task.CompletedTask;
}
public void Dispose() => _timer?.Dispose();
//业务逻辑
private void DailyMethod()
{
Logger.Info($"定时任务触发于 {DateTime.Now:yyyy-MM-dd HH:mm:ss}");
// TODO: 业务逻辑
}
3.注册服务
在 Program.cs(对于 .NET Core 3.1 及以后版本)或 Startup.cs(对于 ASP.NET Core 项目)中注册 TimedBackgroundService。
修改 Program.cs
对于 .NET Core 3.1 及以后的版本,通常在 Program.cs 中配置主机服务。
public class Program
{
public static async Task Main(string[] args)
{
var host = CreateHostBuilder(args).Build();
// 配置 TimedBackgroundService 作为 IHostedService 实现
await host.RunAsync();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<TimedBackgroundService>();//实现了 IHostedService 接口的类
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>(); // 如果你有 Startup 类
});
}
修改 Startup.cs
如果你的项目是基于 ASP.NET Core 的,并且你有一个 Startup.cs 文件,你也可以在 ConfigureServices 方法中注册服务:
public void ConfigureServices(IServiceCollection services)
{
services.AddHostedService<TimedBackgroundService>();//实现了 IHostedService 接口的类
// 其他服务配置
}
4.运行
运行项目时,实现了IHostedService 接口并成功注册的类会按预定逻辑定时执行。
结论
通过实现 IHostedService 接口并在服务容器中注册,我们可以轻松地在 .NET Core 项目中启动和运行定时任务。这种方法不仅适用于控制台应用程序,也适用于 ASP.NET Core Web 应用程序,提供了一种灵活且强大的后台任务处理方式。










暂无评论内容