asp.net core 3.1使用Quartz案例代码
- 实现效果
- 定时执行作业
- 可通过调用WebApi接口来立即执行作业、停止作业、开启作业
- Job类支持依赖注入
- Nuget添加Quartz的引用
- 创建IJobSchedulerWork
using Quartz; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace WebApplication2.Interface { public interface IJobSchedulerWork { /// <summary> /// 开启任务 /// </summary> /// <typeparam name="T">继承了IJob的class</typeparam> /// <param name="cronStr">cron表达式</param> /// <param name="jobName">job名称</param> /// <param name="jobGroup">job组名</param> public void StartTask<T>(string cronStr, string jobName, string jobGroup) where T : IJob; /// <summary> /// 停止任务 /// </summary> public void Stop(); /// <summary> /// 执行任务 /// </summary> /// <param name="jobName">jobName</param> /// <param name="jobGroup">jobGroup</param> public void ExecuteTask(string jobName, string jobGroup); } }
- 创建JobSchedulerWork继承IJobSchedulerWork
using Quartz; using Quartz.Spi; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using WebApplication2.Interface; namespace WebApplication2.Services { public class JobSchedulerWork : IJobSchedulerWork { private readonly ISchedulerFactory _schedulerFactory; private IScheduler _scheduler; private readonly IJobFactory _iocJobfactory; public JobSchedulerWork(ISchedulerFactory schedulerFactory, IJobFactory iocJobfactory) { this._schedulerFactory = schedulerFactory; _iocJobfactory = iocJobfactory; } /// <summary> /// 开启任务 /// </summary> /// <typeparam name="T">继承了IJob的class</typeparam> /// <param name="cronStr">cron表达式</param> /// <param name="jobName">job名称</param> /// <param name="jobGroup">job组名</param> public async void StartTask<T>(string cronStr, string jobName, string jobGroup) where T : IJob { //通过调度工厂获得调度器 _scheduler = await _schedulerFactory.GetScheduler(); _scheduler.JobFactory = _iocJobfactory; //开启调度器 await _scheduler.Start(); //创建一个触发器 var trigger = TriggerBuilder.Create() .WithSchedule(CronScheduleBuilder.CronSchedule(cronStr))//配置确认执行时间 .Build(); //创建任务 var jobDetail = JobBuilder.Create<T>() .WithIdentity(jobName, jobGroup) .Build(); //将触发器和任务器绑定到调度器中 await _scheduler.ScheduleJob(jobDetail, trigger); } /// <summary> /// 停止任务 /// </summary> public async void Stop() { _scheduler = await _schedulerFactory.GetScheduler(); await _scheduler.Shutdown(); } /// <summary> /// 执行任务 /// </summary> /// <param name="jobName"></param> /// <param name="jobGroup"></param> public async void ExecuteTask(string jobName, string jobGroup) { _scheduler = await _schedulerFactory.GetScheduler(); var jobKey = JobKey.Create(jobName, jobGroup); await _scheduler.TriggerJob(jobKey); } } }
- 创建CreateTestDataJob继承IJob
using Microsoft.Extensions.Logging; using Quartz; using System; using System.Threading.Tasks; namespace WebApplication2.Services { public class CreateTestDataJob : IJob { private readonly ILogger<CreateTestDataJob> _logger; public CreateTestDataJob(ILogger<CreateTestDataJob> logger) { _logger = logger; } public Task Execute(IJobExecutionContext context) { return Task.Run(() => { _logger.LogInformation($"执行了一次任务,当前时间:【{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}】"); }); } } }
- 创建IOCJobFactory继承IJobFactory
using Quartz; using Quartz.Spi; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace WebApi.model.Quartz { public class IOCJobFactory : IJobFactory { private readonly IServiceProvider _serviceProvider; public IOCJobFactory(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider; } public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler) { return _serviceProvider.GetService(bundle.JobDetail.JobType) as IJob; } public void ReturnJob(IJob job) { var disposable = job as IDisposable; disposable?.Dispose(); } } }
- 在Startup中配置依赖关系以及配置网站启动时自启动定时作业
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Quartz; using Quartz.Impl; using Quartz.Spi; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using WebApplication2.Interface; using WebApplication2.Services; namespace WebApplication2 { public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddControllers(); services.AddSwaggerGen(c=> { c.SwaggerDoc("v1", new Microsoft.OpenApi.Models.OpenApiInfo() { Title = "WebApplication2", Version = "v1" }); }); services.AddTransient<CreateTestDataJob>(); services.AddSingleton<ISchedulerFactory, StdSchedulerFactory>();//注册ISchedulerFactory的实例。 services.AddSingleton<IJobSchedulerWork, JobSchedulerWork>(); services.AddSingleton<IJobFactory, IOCJobFactory>(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IHostApplicationLifetime applicationLeftTime) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseSwagger(); app.UseSwaggerUI(c=> { c.SwaggerEndpoint("/swagger/v1/swagger.json", "WebApplication2 v1"); }); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); var quartz = app.ApplicationServices.GetRequiredService<IJobSchedulerWork>(); //网站启动自启动定时作业 applicationLeftTime.ApplicationStarted.Register(() => { //成本费用功能抓取数据定时任务 string cronStr = "0/30 * * * * ? "; string jobName = "TestJob"; string jobGroup = "TestGroup"; quartz.StartTask<CreateTestDataJob>(cronStr, jobName, jobGroup); }); //网站停止时关闭Quartz定时作业 applicationLeftTime.ApplicationStopped.Register(() => { quartz.Stop(); }); } } }
- 结果
- 编写一个WebApi,用于立即执行指定的定时任务以及开始和停止任务。
using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using System; using WebApplication2.Interface; using WebApplication2.Services; namespace WebApplication2.Controllers { [Route("api/[controller]")] [ApiController] public class TestDataJobController : ControllerBase { private readonly IJobSchedulerWork _jobSchedulerWork; private readonly ILogger<TestDataJobController> _logger; public TestDataJobController(IJobSchedulerWork jobSchedulerWork, ILogger<TestDataJobController> logger) { this._logger = logger; this._jobSchedulerWork = jobSchedulerWork; } /// <summary> /// 立即执行CreateTestDataJob作业 /// </summary> /// <returns></returns> [HttpPost("ExecuteCreateTestDataJob")] public object ExecuteCreateTestDataJob() { try { _jobSchedulerWork.ExecuteTask("TestJob", "TestGroup"); return new { code = 200, msg = "执行任务成功" }; } catch (Exception exp) { return new { code = 500, msg = string.Format("{0}", exp) }; } } /// <summary> /// 开启CreateTestDataJob作业 /// </summary> /// <returns></returns> [HttpPost("StartCreateTestDataJob")] public object StartCreateTestDataJob() { try { _jobSchedulerWork.StartTask<CreateTestDataJob>("0/30 * * * * ? ", "TestJob", "TestGroup"); return new { code = 200, msg = "开启作业成功" }; } catch (Exception exp) { return new { code = 500, msg = string.Format("{0}", exp) }; } } /// <summary> /// 关闭CreateTestDataJob作业 /// </summary> /// <returns></returns> [HttpPost("StopCreateTestDataJob")] public object StopCreateTestDataJob() { try { _jobSchedulerWork.Stop(); return new { code = 200, msg = "关闭作业成功" }; } catch (Exception exp) { return new { code = 500, msg = string.Format("{0}", exp) }; } } } }