【技术教程】.NET Core 简单定时任务

介绍

定时任务又称“计划任务”,是指在预定的时间点或周期自动触发并执行的一段业务逻辑。它把“人工操作”变为“系统自动完成”。

System.Threading.Timer 是 .NET 里最轻量的后台定时器,主要有三个特点:

  1. 指定毫秒后第一次触发回调;
  2. 之后按固定间隔重复(可设为 Timeout.Infinite 只跑一次);
  3. 全程由线程池线程执行,不占用 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 应用程序,提供了一种灵活且强大的后台任务处理方式。

© 版权声明
THE END
喜欢就支持一下吧
点赞12 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容