Introduction:
Quartz.NET contains a simple API for implementing scheduled jobs and offers a wealth of scheduling options. For example, If you need to run your services at a particular interval like every 5 minutes then Quartz is very useful. In this article, we install Quartz in our existing application and perform scheduling on our services.
Get Started:
Step 1: Install the Quartz in your application.
Right-click on the main project and select Manage Nuget Packages
Browse the Quartz and install the latest version.
Step 2: Create a Schedulers folder.
Well, to perform the scheduling, we need 4 to 5 .cs files. So, create a new Schedulers folder in your application.
Right-click on your application and select the new folder.
Step 3: Add JobSchedule class in the Schedulers folder.
using System; namespace URLTester.Schedulers { public class JobSchedule { public JobSchedule(Type jobType, string cronExpression) { JobType = jobType; CronExpression = cronExpression; } public Type JobType { get; } public string CronExpression { get; } } }
Step 4: Add QuartzHostedService class in the Schedulers folder.
using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Hosting; using Quartz; using Quartz.Spi; namespace URLTester.Schedulers { 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(); } } }
Step 5: Add QuartzRunner class to the Schedulers folder.
using Microsoft.Extensions.DependencyInjection; using Quartz; using System; using System.Threading.Tasks; namespace URLTester.Schedulers { public class QuartzRunner : IJob { private readonly IServiceProvider _serviceProvider; public QuartzRunner(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider; } public async Task Execute(IJobExecutionContext context) { using (var scope = _serviceProvider.CreateScope()) { var job = scope.ServiceProvider.GetRequiredService(context.JobDetail.JobType) as IJob; await job.Execute(context); } } } }
Step 6: Add SingletonJobFactory class in the Schedulers folder.
using Microsoft.Extensions.DependencyInjection; using Quartz; using Quartz.Spi; using System; namespace URLTester.Schedulers { public class SingletonJobFactory : IJobFactory { private readonly IServiceProvider _serviceProvider; public SingletonJobFactory(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider; } public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler) { return _serviceProvider.GetRequiredService<QuartzRunner>(); } public void ReturnJob(IJob job) { } } }
Step 7: Add APIScheduler class in the Schedulers folder.
using Quartz; using System.Threading.Tasks; using URLTester.Interfaces; namespace URLTester.Schedulers { public class APIScheduler : IJob { private readonly IUrlTestingService _urlTestingService; public APIScheduler(IUrlTestingService urlTestingService) { _urlTestingService = urlTestingService; } public Task Execute(IJobExecutionContext context) { //Add your scheduling task here . . . _urlTestingService.UpdateStatusOfAllUrl().Wait(); return Task.CompletedTask; } } }
Step 8: Define Quartz in the Startup.cs file
public void ConfigureServices(IServiceCollection services) { . . . // Add Quartz services services.AddHostedService<QuartzHostedService>(); services.AddSingleton<IJobFactory, SingletonJobFactory>(); services.AddSingleton<ISchedulerFactory, StdSchedulerFactory>(); services.AddSingleton<QuartzRunner>(); // Add our job services.AddScoped<APIScheduler>(); services.AddSingleton(new JobSchedule( jobType: typeof(APIScheduler), cronExpression: "0 0/5 * 1/1 * ? *")); //Run every 5 minutes services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); }
Finally, run your application and you can see that Quartz runs your services every 5 minutes.