前言
Quartz.Net是一个开源的作业调度框架,可以用于管理计划任务和定期执行。Quartz.Net提供了丰富的作业计划选项,例如精确或模糊时间表达式、日期和时间限制等。Quartz.Net采用分布式架构,允许在多个计算机上运行任务。
Quartz.Net架构设计
Quartz.Net的架构设计采用了经典的MVC(Model-View-Controller)模式,其中:
- Model:表示应用程序中的数据和状态。在Quartz.Net中,Model由Job和Trigger组成,并由Scheduler调度。
- View:表示与用户交互的部分。在Quartz.Net中,View由Scheduler框架提供的API和UI组件组成。
- Controller:负责处理用户输入并更新Model和View。在Quartz.Net中,Controller由Scheduler控制器组成。
Quartz.Net组件模块
Quartz.Net包含以下组件模块:
- Scheduler:负责作业的调度和执行。Scheduler维护一个作业和触发器的调度列表,并根据定义的条件选择要调度的作业。
- Job:表示要执行的作业。在Quartz.Net中,Job必须实现IJob接口。
- Trigger:定义何时执行作业。在Quartz.Net中,有多种类型的触发器可供选择,例如简单触发器、Cron触发器等。
- JobDetail:表示作业的详细信息,包括执行作业所需的Job类及其名称、描述和其他数据。
- JobExecutionContext:在作业执行期间提供与应用程序和Quartz.Net框架交互所需的上下文信息。
- SchedulerFactory:用于创建Scheduler的工厂类。
集成Quartz.Net
在NetCore项目中集成Quartz.Net,可以通过以下步骤实现:
-
安装Quartz.Net NuGet包
在Visual Studio的NuGet包管理器中搜索安装Quartz.Net包,或通过命令行安装:dotnet add package Quartz。 -
创建作业类
依据项目需求创建对应的作业类,并实现IJob接口,例如:
public class MyJob : IJob
{public async Task Execute(IJobExecutionContext context){await Console.Out.WriteLineAsync("Hello, Quartz.Net!");}
}
- 配置Scheduler
在Startup.cs文件中添加配置代码,创建Scheduler,添加作业和触发器:
public void ConfigureServices(IServiceCollection services)
{services.AddSingleton<IJobFactory, SingletonJobFactory>();services.AddSingleton<ISchedulerFactory, StdSchedulerFactory>();services.AddSingleton(new JobSchedule(jobType: typeof(MyJob),cronExpression: "0/5 * * * * ?")); // 每5秒执行一次services.AddHostedService<QuartzHostedService>();
}public class JobSchedule
{public Type JobType { get; }public string CronExpression { get; }public JobSchedule(Type jobType, string cronExpression){JobType = jobType;CronExpression = cronExpression;}
}public class SingletonJobFactory : IJobFactory
{private readonly IServiceProvider _serviceProvider;public SingletonJobFactory(IServiceProvider serviceProvider){_serviceProvider = serviceProvider;}public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler){return (IJob)_serviceProvider.GetService(bundle.JobDetail.JobType);}public void ReturnJob(IJob job){// do nothing}
}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;_jobFactory = jobFactory;_jobSchedules = jobSchedules;}public async Task StartAsync(CancellationToken cancellationToken){var scheduler = await _schedulerFactory.GetScheduler(cancellationToken);scheduler.JobFactory = _jobFactory;foreach (var jobSchedule in _jobSchedules){var jobDetail = JobBuilder.Create(jobSchedule.JobType).Build();var trigger = TriggerBuilder.Create().WithCronSchedule(jobSchedule.CronExpression).Build();await scheduler.ScheduleJob(jobDetail, trigger, cancellationToken);}await scheduler.Start(cancellationToken);}public async Task StopAsync(CancellationToken cancellationToken){var scheduler = await _schedulerFactory.GetScheduler(cancellationToken);await scheduler.Shutdown(cancellationToken);}
}
- 启动和停止Scheduler
在Main函数中启动调度程序:
public static async Task Main(string[] args)
{var host = CreateHostBuilder(args).Build();await host.RunAsync();
}