In my case I am enqueueing messages to a queue in Run()
method. After the job is fired for the first time, another instance starts each time interval passes, and they continue to work together. How can I prevent a new one from starting if there is an active instance? It is a .netcore 3.1 project. I tried with Quartz 3.2.0 and 3.2.4. Here is job scheduling, JobFactory and Job, sequentially.
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Quartz;
using Quartz.Impl;
using Quartz.Spi;
using System.Collections.Specialized;
using System.Threading;
using System.Threading.Tasks;
using WinSchedulerLib;
namespace MessageSender.WinService
{
public class MessageSenderService : IHostedService
{
public static IScheduler scheduler;
public static IJobFactory jobFactory;
public async Task StartAsync(CancellationToken cancellationToken)
{
var props = new NameValueCollection { { "quartz.serializer.type", "binary" } };
var factory = new StdSchedulerFactory(props);
var scheduler = await factory.GetScheduler();
var services = new ServiceCollection().AddScoped<IJob, MessageSenderJob>();
var serviceProvider = services.BuildServiceProvider();
jobFactory = new JobFactory(serviceProvider);
scheduler.JobFactory = jobFactory;
await scheduler.Start();
await scheduler.ScheduleJob(
JobBuilder
.Create<IJob>()
.WithIdentity("SenderJob", "SenderGroup")
.Build(),
TriggerBuilder
.Create()
.WithIdentity("SenderJob", "SenderGroup")
.StartNow()
.WithCronSchedule("0 */10 * ? * *")
.Build());
await Task.Delay(1000);
}
public Task StopAsync(CancellationToken cancellationToken)
{
return Task.CompletedTask;
}
}
}
using Quartz;
using Quartz.Spi;
using System;
namespace WinSchedulerLib
{
public class JobFactory : IJobFactory
{
protected readonly IServiceProvider _serviceProvider;
public JobFactory(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 obj = job as IDisposable;
obj?.Dispose();
}
}
}
using Quartz;
using System.Threading.Tasks;
namespace MessageSender.WinService
{
[DisallowConcurrentExecution]
public class MessageSenderJob : IJob
{
public async Task Execute(IJobExecutionContext context)
{
var sender = new DefaultServiceBusSender();
await sender.Run();
}
}
}