.netCore 使用Quartz做定时任务
参考:https://www.cnblogs.com/LinWenQiang/p/13460283.html
Quartz 由三个部分组成,分别为Schedule(调度器)、Trigger(触发器)、JobDetail(任务)
1、首先在项目中添加Quartz nuget 包。
2、创建我们的任务,在项目中添加MyJob,并继承接口Ijob
[DisallowConcurrentExecution] public class MyJob : IJob { private readonly ILogger<MyJob> _logger; public MyJob(ILogger<MyJob> logger) { _logger = logger; } public Task Execute(IJobExecutionContext context) { _logger.LogInformation("MyJob start"); //在此处编写任务业务代码 return Task.CompletedTask; } }
DisallowConcurrentExecution:防止运行多个相同的实例
3、创建调度类JobSchedule
public class JobSchedule { public JobSchedule(Type jobType, string cronExpression) { this.JobType = jobType ?? throw new ArgumentNullException(nameof(jobType)); CronExpression = cronExpression ?? throw new ArgumentNullException(nameof(cronExpression)); } /// <summary> /// Job类型 /// </summary> public Type JobType { get; private set; } /// <summary> /// Cron表达式 /// </summary> public string CronExpression { get; private set; } /// <summary> /// Job状态 /// </summary> public JobStatus JobStatu { get; set; } = JobStatus.Init; } /// <summary> /// Job运行状态 /// </summary> public enum JobStatus : byte { [Description("初始化")] Init = 0, [Description("运行中")] Running = 1, [Description("调度中")] Scheduling = 2, [Description("已停止")] Stopped = 3, }
4、添加调度工厂SingletonJobFactory
public class SingletonJobFactory: IJobFactory { private readonly IServiceScope _serviceScope; public SingletonJobFactory(IServiceProvider serviceProvider) { _serviceScope = serviceProvider.CreateScope(); } public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler) { return _serviceScope.ServiceProvider.GetRequiredService(bundle.JobDetail.JobType) as IJob; } public void ReturnJob(IJob job) { (job as IDisposable)?.Dispose(); } }
5、创建QuartzHostedService类,并继承 IHostedService
public class QuartzHostedService : IHostedService { private readonly IJobFactory _jobFactory; private readonly IEnumerable<JobSchedule> _jobSchedules; public QuartzHostedService(IJobFactory jobFactory, IEnumerable<JobSchedule> jobSchedules) { _jobSchedules = jobSchedules; _jobFactory = jobFactory; } public IScheduler Scheduler { get; set; } public async Task StartAsync(CancellationToken cancellationToken) { Scheduler = await StdSchedulerFactory.GetDefaultScheduler(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(); } }
6、在Startup进行注册
public void ConfigureServices(IServiceCollection services) { //添加Quartz服务 services.AddSingleton<IJobFactory, SingletonJobFactory>(); services.AddSingleton<ISchedulerFactory, StdSchedulerFactory>(); //添加我们的Job services.AddScoped<MyJob>();//这里注册时有个坑,一定要注意 services.AddSingleton( new JobSchedule(jobType: typeof(MyJob), cronExpression: Configuration["TimingTask"]) ); // ... }
定时时间我这里写到appsettings.json配置文件中了,方便更改:
"TimingTask": "0 45 10 * * ?",
关于Cron表达式,可以看官方文档:
https://www.quartz-scheduler.net/documentation/quartz-3.x/tutorial/crontrigger.html#examples