Implement Quartz In ASP .NET Core

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.

Submit a Comment

Your email address will not be published. Required fields are marked *

Subscribe

Select Categories