.Net Core中使用Quartz实现后台定时任务
阿里云优惠活动
一、Quartz介绍
Quartz项目地址:https://github.com/quartz-scheduler/quartz
里面可以看到介绍:
Quartz is a richly featured, open source job scheduling library that can be integrated within virtually any Java application - from the smallest stand-alone application to the largest e-commerce system.
.Net Core可以通过hosted services很好的实现后台任务,Hosted services跟随.Net Core应用启动而在后台启动。创建一个Quartz.NET的host service可以使用Quartz
Quartz可以通过其Cron表达式实现复杂定时规则的定时任务。
二、引用相关类库
在Nuget中引用类库:Quartz.Net
三、创建Job
创建的Job要实现IJob,我们这里创建两个Job:
[DisallowConcurrentExecution] public class HelloWorldJob : IJob { private readonly ILogger<HelloWorldJob> _logger; public HelloWorldJob(ILogger<HelloWorldJob> logger) { _logger = logger; } public Task Execute(IJobExecutionContext context) { _logger.LogInformation("Hello world!"); return Task.CompletedTask; } }
[DisallowConcurrentExecution] public class IntroduceJob : IJob { private readonly ILogger<IntroduceJob> _logger; public IntroduceJob(ILogger<IntroduceJob> logger) { _logger = logger; } public Task Execute(IJobExecutionContext context) { _logger.LogInformation("My name is yang"); return Task.CompletedTask; } }
关于特性DisallowConcurrentExecution的介绍可以看这里:DisallowConcurrentExecution防止运行多个相同的任务实例
四、创建JobFactory
public class SingletonJobFactory : IJobFactory { private readonly IServiceProvider _serviceProvider; public SingletonJobFactory(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider; } public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler) { return _serviceProvider.GetRequiredService(bundle.JobDetail.JobType) as IJob; } public void ReturnJob(IJob job) { } }
五、配置Job
配置Job我们创建一个类JobSchedule
public class JobSchedule { public JobSchedule(Type jobType, string cronExpression) { JobType = jobType; CronExpression = cronExpression; } public Type JobType { get; } public string CronExpression { get; } }
六、在StartUp的ConfigureServices中注入
// Add Quartz services services.AddSingleton<IJobFactory, SingletonJobFactory>(); services.AddSingleton<ISchedulerFactory, StdSchedulerFactory>(); // Add our job services.AddSingleton<HelloWorldJob>(); services.AddSingleton<IntroduceJob>(); services.AddJob(); services.AddHostedService<QuartzHostedService>();
创建ServiceCollectionExtensions注入schedule
public static class ServiceCollectionExtensions { public static void AddJob(this IServiceCollection services) { services.AddSingleton(new JobSchedule( jobType: typeof(HelloWorldJob), cronExpression: "0/2 * * * * ?")); // run every 2 seconds services.AddSingleton(new JobSchedule( jobType: typeof(IntroduceJob), cronExpression: "0/5 * * * * ?")); } }
七、创建QuartzHostedService
public class QuartzHostedService : IHostedService { private readonly ISchedulerFactory _schedulerFactory; private readonly IJobFactory _jobFactory; private readonly IEnumerable<JobSchedule> _jobSchedules; public QuartzHostedService( ISchedulerFactory schedulerFactory, IJobFactory jobFactory, IEnumerable<JobSchedule> jobSchedules) { _schedulerFactory = schedulerFactory; _jobSchedules = jobSchedules; _jobFactory = jobFactory; } public IScheduler Scheduler { get; set; } public async Task StartAsync(CancellationToken cancellationToken) { Scheduler = await _schedulerFactory.GetScheduler(cancellationToken); Scheduler.JobFactory = _jobFactory; foreach (var jobSchedule in _jobSchedules) { var job = CreateJob(jobSchedule); var trigger = CreateTrigger(jobSchedule); await Scheduler.ScheduleJob(job, trigger, cancellationToken); } await Scheduler.Start(cancellationToken); } public async Task StopAsync(CancellationToken cancellationToken) { await Scheduler?.Shutdown(cancellationToken); } private static IJobDetail CreateJob(JobSchedule schedule) { var jobType = schedule.JobType; return JobBuilder .Create(jobType) .WithIdentity(jobType.FullName) .WithDescription(jobType.Name) .Build(); } private static ITrigger CreateTrigger(JobSchedule schedule) { return TriggerBuilder .Create() .WithIdentity($"{schedule.JobType.FullName}.trigger") .WithCronSchedule(schedule.CronExpression) .WithDescription(schedule.CronExpression) .Build(); } }
八、运行程序
可以看到如下效果