Administrator
发布于 2025-08-08 / 3 阅读
0
0

dotnet定时任务

在 .NET 生态中,有多个成熟的定时任务组件可用于实现周期性任务、延迟任务等场景,从简单的轻量工具到复杂的分布式调度系统应有尽有。以下是常用的定时任务组件及使用示例:

一、轻量级组件(单进程 / 简单场景)

1. System.Timers.Timer(.NET 内置)

最基础的定时组件,适合简单的周期性任务,无需额外依赖。

特点

  • 基于 System.ComponentModel.Component,事件驱动

  • 支持设置间隔时间(Interval),单位为毫秒

  • 简单易用,但功能有限(无 cron 表达式、无任务管理)

示例

using System;
using System.Timers;
​
class Program
{
    static void Main()
    {
        // 创建定时器,每5秒执行一次
        var timer = new Timer(5000);
        timer.Elapsed += OnTimedEvent; // 绑定事件
        timer.AutoReset = true; // 自动重复
        timer.Enabled = true;   // 启动定时器
​
        Console.WriteLine("定时器已启动,按Enter退出...");
        Console.ReadLine();
        timer.Stop();
        timer.Dispose();
    }
​
    // 定时执行的方法
    private static void OnTimedEvent(object? sender, ElapsedEventArgs e)
    {
        Console.WriteLine($"定时任务执行:{DateTime.Now:HH:mm:ss}");
    }
}

2. Quartz.NET(功能全面的标准库)

.NET 领域最流行的定时任务框架,支持复杂调度策略(如 cron 表达式、任务依赖、错过执行处理等)。

特点

  • 支持 cron 表达式(如 0 0 12 * * ? 每天中午执行)

  • 任务持久化(可存储到数据库,支持服务重启后恢复)

  • 支持任务并发控制、优先级、集群部署

使用步骤

  1. 安装包:

Install-Package Quartz
  1. 示例代码:

using Quartz;
using Quartz.Impl;
using System;
using System.Threading.Tasks;
​
// 定义任务
public class MyJob : IJob
{
    public Task Execute(IJobExecutionContext context)
    {
        Console.WriteLine($"Quartz任务执行:{DateTime.Now:HH:mm:ss}");
        return Task.CompletedTask;
    }
}
​
class Program
{
    static async Task Main()
    {
        // 创建调度器
        var schedulerFactory = new StdSchedulerFactory();
        var scheduler = await schedulerFactory.GetScheduler();
        await scheduler.Start();
​
        // 创建任务
        var job = JobBuilder.Create<MyJob>()
            .WithIdentity("job1", "group1")
            .Build();
​
        // 创建触发器(每3秒执行一次)
        var trigger = TriggerBuilder.Create()
            .WithIdentity("trigger1", "group1")
            .StartNow()
            .WithSimpleSchedule(x => x
                .WithIntervalInSeconds(3)
                .RepeatForever())
            .Build();
​
        // 或者使用cron表达式(每天10:30执行)
        // var trigger = TriggerBuilder.Create()
        //     .WithCronSchedule("0 30 10 * * ?")
        //     .Build();
​
        // 关联任务和触发器
        await scheduler.ScheduleJob(job, trigger);
​
        Console.WriteLine("Quartz调度器已启动,按Enter退出...");
        Console.ReadLine();
        await scheduler.Shutdown();
    }
}

3.Coravel(轻量级任务调度框架)

Coravel 是专为 .NET Core 设计的轻量级框架,集成了任务调度、队列等功能,API 简洁,适合在 ASP.NET Core 中使用。

特点:

  • 支持 cron 表达式(如 * * * * * 每分钟执行)

  • ASP.NET Core 生命周期无缝集成

  • 无需数据库,内存调度(适合非分布式场景)

使用步骤:

  1. 安装包:

Install-Package Coravel
  1. ASP.NET Core 中使用:

  • 编写示例job

    /// <summary>
    /// 定时任务 - 测试参数
    /// </summary>
    public class TestJobArgs
    {
    }
    ​
    /// <summary>
    /// 定时任务 - 测试Job
    /// </summary>
    public class TestJob : AsyncBackgroundJob<TestJobArgs> , ITransientDependency
    {
        private readonly ITestService _testService;
    ​
        public TestJob(ITestService testService)
        {
            _testService = testService;
        }
    ​
        public async override Task ExecuteAsync(TestJobArgs args)
        {
            await _testService.Test(args);
        }
    }
    ​
    // public class TestJob: IInvocable
    // {
        
    // }
  • 注册定时任务

    // Program.cs
    using Coravel;
    ​
    var builder = WebApplication.CreateBuilder(args);
    ​
    // 注册 Coravel 调度服务
    builder.Services.AddScheduler();
    // Program.cs 中注册任务类(支持依赖注入)
    builder.Services.AddTransient<CleanupJob>();
    builder.Services.AddTransient<DataSyncJob>();
    ​
    var app = builder.Build();
    ​
    // 配置定时任务
    app.Services.UseScheduler(scheduler =>
    {
        // 每5秒执行一次
        scheduler.Schedule(() => Console.WriteLine($"Coravel任务:{DateTime.Now:HH:mm:ss}")).EverySeconds(5);
    ​
        // 使用cron表达式:每天10:00执行
        scheduler.Schedule(() => Console.WriteLine("每日任务执行")).Cron("0 0 10 * * *");
        
        // 每小时执行清理任务
        // scheduler.Schedule<TestJob>().Hourly();
    ​
        // 每30分钟执行数据同步任务(异步)
        scheduler.Schedule<TestJob>().EveryThirtyMinutes().RunOnceAtStart(); // 启动时立即执行一次
    });
    ​
    app.Run();

二、ASP.NET Core 集成方案

1. BackgroundService(.NET Core 内置)

适合在 ASP.NET Core 应用中运行后台任务,基于 IHostedService 接口。

特点

  • ASP.NET Core 生命周期集成(自动随应用启动 / 停止)

  • 适合长时间运行的后台任务,可结合 Timer 实现定时逻辑

示例

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
using System.Threading;
using System.Threading.Tasks;
​
// 定义后台任务
public class TimedHostedService : BackgroundService
{
    private readonly PeriodicTimer _timer = new(TimeSpan.FromSeconds(4)); // 每4秒执行
​
    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (await _timer.WaitForNextTickAsync(stoppingToken) && !stoppingToken.IsCancellationRequested)
        {
            Console.WriteLine($"BackgroundService执行:{DateTime.Now:HH:mm:ss}");
        }
    }
}
​
// 注册服务(Program.cs)
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHostedService<TimedHostedService>(); // 注册后台任务
​
var app = builder.Build();
app.Run();

2. Hangfire(易用的企业级框架)

专注于后台任务和定时任务,支持 Dashboard 可视化管理,适合业务系统中的定时任务(如订单超时处理、报表生成)。

特点

  • 提供 Web Dashboard 监控任务执行情况

  • 支持持久化(SQL Server、Redis 等)

  • 自动重试失败任务,支持任务取消

  • 语法简洁,支持 cron 表达式

使用步骤

  1. 安装包(以 SQL Server 为例):

Install-Package Hangfire
Install-Package Hangfire.SqlServer
  1. 示例代码(ASP.NET Core):

// Program.cs
using Hangfire;
using Hangfire.SqlServer;
​
var builder = WebApplication.CreateBuilder(args);
​
// 配置Hangfire(使用SQL Server存储)
builder.Services.AddHangfire(config => config
    .SetDataCompatibilityLevel(CompatibilityLevel.Version_180)
    .UseSimpleAssemblyNameTypeSerializer()
    .UseRecommendedSerializerSettings()
    .UseSqlServerStorage(builder.Configuration.GetConnectionString("HangfireConnection"),
        new SqlServerStorageOptions
        {
            CommandBatchMaxTimeout = TimeSpan.FromMinutes(5),
            SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5),
            QueuePollInterval = TimeSpan.Zero
        }));
​
// 添加Hangfire服务
builder.Services.AddHangfireServer();
​
var app = builder.Build();
​
// 启用Hangfire Dashboard(访问 /hangfire 查看)
app.UseHangfireDashboard();
​
// 定义定时任务
RecurringJob.AddOrUpdate(
    "my-recurring-job",
    () => Console.WriteLine($"Hangfire任务执行:{DateTime.Now:HH:mm:ss}"),
    "*/2 * * * *"); // cron表达式:每2分钟执行一次
​
app.Run();
  1. 配置连接字符串(appsettings.json):

{
  "ConnectionStrings": {
    "HangfireConnection": "Server=.;Database=Hangfire;Trusted_Connection=True;TrustServerCertificate=True"
  }
}

三、分布式定时任务(多实例 / 集群场景)

1. Hangfire 集群模式

Hangfire 支持多实例部署,通过共享数据库自动实现任务分发,避免重复执行。只需多个实例连接同一数据库,无需额外配置。

2. Quartz.NET 集群

通过数据库实现分布式锁,确保任务在集群中仅执行一次。需配置集群参数:

// 集群配置(quartz.config)
quartz.scheduler.instanceName = MyClusteredScheduler
quartz.scheduler.instanceId = AUTO
quartz.jobStore.type = Quartz.Impl.AdoJobStore.JobStoreTX, Quartz
quartz.jobStore.useProperties = true
quartz.jobStore.dataSource = default
quartz.jobStore.clustered = true // 启用集群
quartz.dataSource.default.connectionString = Server=.;Database=Quartz;Trusted_Connection=True
quartz.dataSource.default.provider = SqlServer

四、组件对比与选择建议

组件

特点

适用场景

System.Timers.Timer

轻量、内置、无依赖

简单周期性任务,非ASP.NET Core 环境

Quartz.NET

功能全面、支持 cron、集群

复杂调度逻辑,需持久化和集群支持

BackgroundService

ASP.NET Core 集成,适合后台任务

简单定时任务,需随 Web 应用生命周期管理

Hangfire

Dashboard、易用、自动重试、集群友好

业务系统中的定时任务(如订单处理、报表)

五、总结

  • 简单工具 / 控制台应用:优先用 System.Timers.TimerQuartz.NET

  • ASP.NET Core 应用:简单场景用 BackgroundService,复杂场景用 Hangfire

  • 分布式系统Hangfire(简单)或 Quartz.NET 集群(复杂控制)


评论