How to start Quartz in ASP.NET Core?

后端 未结 5 1382
你的背包
你的背包 2020-12-02 07:00

I have the following class

 public class MyEmailService
 {
    public async Task SendAdminEmails()
    {
        ...
    }
    public async Task&         


        
5条回答
  •  时光取名叫无心
    2020-12-02 07:27

    The accepted answer covers the topic very well, but some things have changed with the latest Quartz version. The following is based on this article shows a quick start with Quartz 3.0.x and ASP.NET Core 2.2:

    Util class

    public class QuartzServicesUtilities
    {
        public static void StartJob(IScheduler scheduler, TimeSpan runInterval)
            where TJob : IJob
        {
            var jobName = typeof(TJob).FullName;
    
            var job = JobBuilder.Create()
                .WithIdentity(jobName)
                .Build();
    
            var trigger = TriggerBuilder.Create()
                .WithIdentity($"{jobName}.trigger")
                .StartNow()
                .WithSimpleSchedule(scheduleBuilder =>
                    scheduleBuilder
                        .WithInterval(runInterval)
                        .RepeatForever())
                .Build();
    
            scheduler.ScheduleJob(job, trigger);
        }
    }
    

    Job factory

    public class QuartzJobFactory : IJobFactory
    {
        private readonly IServiceProvider _serviceProvider;
    
        public QuartzJobFactory(IServiceProvider serviceProvider)
        {
            _serviceProvider = serviceProvider;
        }
    
        public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
        {
            var jobDetail = bundle.JobDetail;
    
            var job = (IJob)_serviceProvider.GetService(jobDetail.JobType);
            return job;
        }
    
        public void ReturnJob(IJob job) { }
    }
    

    A job sample that also deals with exiting on application pool recycle / exit

    [DisallowConcurrentExecution]
    public class TestJob : IJob
    {
        private ILoggingService Logger { get; }
        private IApplicationLifetime ApplicationLifetime { get; }
    
        private static object lockHandle = new object();
        private static bool shouldExit = false;
    
        public TestJob(ILoggingService loggingService, IApplicationLifetime applicationLifetime)
        {
            Logger = loggingService;
            ApplicationLifetime = applicationLifetime;
        }
    
        public Task Execute(IJobExecutionContext context)
        {
            return Task.Run(() =>
            {
                ApplicationLifetime.ApplicationStopping.Register(() =>
                {
                    lock (lockHandle)
                    {
                        shouldExit = true;
                    }
                });
    
                try
                {
                    for (int i = 0; i < 10; i ++)
                    {
                        lock (lockHandle)
                        {
                            if (shouldExit)
                            {
                                Logger.LogDebug($"TestJob detected that application is shutting down - exiting");
                                break;
                            }
                        }
    
                        Logger.LogDebug($"TestJob ran step {i+1}");
                        Thread.Sleep(3000);
                    }
                }
                catch (Exception exc)
                {
                    Logger.LogError(exc, "An error occurred during execution of scheduled job");
                }
            });
        }
    }
    

    Startup.cs configuration

    private void ConfigureQuartz(IServiceCollection services, params Type[] jobs)
    {
        services.AddSingleton();
        services.Add(jobs.Select(jobType => new ServiceDescriptor(jobType, jobType, ServiceLifetime.Singleton)));
    
        services.AddSingleton(provider =>
        {
            var schedulerFactory = new StdSchedulerFactory();
            var scheduler = schedulerFactory.GetScheduler().Result;
            scheduler.JobFactory = provider.GetService();
            scheduler.Start();
            return scheduler;
        });
    }
    
    protected void ConfigureJobsIoc(IServiceCollection services)
    {
        ConfigureQuartz(services, typeof(TestJob), /* other jobs come here */);
    }
    
    public void ConfigureServices(IServiceCollection services)
    {
        ConfigureJobsIoc(services);
    
        // other stuff comes here
        AddDbContext(services);
        AddCors(services);
    
        services
            .AddMvc()
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    }
    
    
    protected void StartJobs(IApplicationBuilder app, IApplicationLifetime lifetime)
    {
        var scheduler = app.ApplicationServices.GetService();
        //TODO: use some config
        QuartzServicesUtilities.StartJob(scheduler, TimeSpan.FromSeconds(60));
    
        lifetime.ApplicationStarted.Register(() => scheduler.Start());
        lifetime.ApplicationStopping.Register(() => scheduler.Shutdown());
    }
    
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory,
        ILoggingService logger, IApplicationLifetime lifetime)
    {
        StartJobs(app, lifetime);
    
        // other stuff here
    }
    

提交回复
热议问题