Problem: My jobs doesn’t work same times. Allways work only one. What is wrong in code.
Expected runs
**info: exampleProject.Api.Services.QuartzServices.Job1[0]
Job1 is working…
info: exampleProject.Api.Services.QuartzServices.Job2[0]
Job2 is working…**
CustomQuartzHostedService
public class CustomQuartzHostedService : IHostedService
{
private readonly ISchedulerFactory schedulerFactory;
private readonly IJobFactory jobFactory;
private readonly JobMetadata jobMetadata;
public CustomQuartzHostedService(ISchedulerFactory
schedulerFactory,
JobMetadata jobMetadata,
IJobFactory jobFactory)
{
this.schedulerFactory = schedulerFactory;
this.jobMetadata = jobMetadata;
this.jobFactory = jobFactory;
}
public IScheduler Scheduler { get; set; }
public async Task StartAsync(CancellationToken cancellationToken)
{
Scheduler = await schedulerFactory.GetScheduler();
Scheduler.JobFactory = jobFactory;
var job = CreateJob(jobMetadata);
var trigger = CreateTrigger(jobMetadata);
await Scheduler.ScheduleJob(job, trigger, cancellationToken);
await Scheduler.Start(cancellationToken);
}
public async Task StopAsync(CancellationToken cancellationToken)
{
await Scheduler?.Shutdown(cancellationToken);
}
private ITrigger CreateTrigger(JobMetadata jobMetadata)
{
return TriggerBuilder.Create()
.WithIdentity(jobMetadata.JobId.ToString())
.WithCronSchedule(jobMetadata.CronExpression)
.WithDescription($"{jobMetadata.JobName}")
.Build();
}
private IJobDetail CreateJob(JobMetadata jobMetadata)
{
return JobBuilder
.Create(jobMetadata.JobType)
.WithIdentity(jobMetadata.JobId.ToString())
.WithDescription($"{jobMetadata.JobName}")
.Build();
}
}
CustomQuartzJobFactory
public class CustomQuartzJobFactory : IJobFactory
{
private readonly IServiceProvider _serviceProvider;
public CustomQuartzJobFactory(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public IJob NewJob(TriggerFiredBundle triggerFiredBundle,
IScheduler scheduler)
{
var jobDetail = triggerFiredBundle.JobDetail;
return (IJob)_serviceProvider.GetService(jobDetail.JobType);
}
public void ReturnJob(IJob job) { }
}
JobMetadata
public class JobMetadata
{
public Guid JobId { get; set; }
public Type JobType { get; }
public string JobName { get; }
public string CronExpression { get; }
public JobMetadata(Guid Id, Type jobType, string jobName,
string cronExpression)
{
JobId = Id;
JobType = jobType;
JobName = jobName;
CronExpression = cronExpression;
}
}
Job1
[DisallowConcurrentExecution]
public class Job1 : IJob
{
private readonly ILogger<Job1> _logger;
public Job1(ILogger<Job1> logger)
{
_logger = logger;
}
public async Task Execute(IJobExecutionContext context)
{
_logger.LogInformation("Job1 is working...");
}
}
Job2
[DisallowConcurrentExecution]
public class Job2 : IJob
{
private readonly ILogger<Job2> _logger;
public Job2(ILogger<Job2> logger)
{
_logger = logger;
}
public async Task Execute(IJobExecutionContext context)
{
_logger.LogInformation("Job2 is working...");
}
}
Startup.cs
services.AddSingleton<IJobFactory, CustomQuartzJobFactory>();
services.AddSingleton<ISchedulerFactory, StdSchedulerFactory>();
services.AddSingleton<Job1>();
services.AddSingleton<Job2>();
services.AddSingleton(new JobMetadata(Guid.NewGuid(), typeof(Job1), "Job1 Defination", "0/10 * * ? * * *")); //Every 10 seconds
services.AddSingleton(new JobMetadata(Guid.NewGuid(), typeof(Job2), "Job2 Defination", "0/10 * * ? * * *")); //Every 10 seconds
services.AddHostedService<CustomQuartzHostedService>();
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
Here is a working demo:
Change JobMetadata jobMetadata to List in CustomQuartzHostedService:
public class CustomQuartzHostedService: IHostedService
{
private readonly ISchedulerFactory schedulerFactory;
private readonly IJobFactory jobFactory;
private readonly List<JobMetadata> jobMetadatas;
public CustomQuartzHostedService(ISchedulerFactory
schedulerFactory,
List<JobMetadata> jobMetadatas,
IJobFactory jobFactory)
{
this.schedulerFactory = schedulerFactory;
this.jobMetadatas = jobMetadatas;
this.jobFactory = jobFactory;
}
public IScheduler Scheduler { get; set; }
public async Task StartAsync(CancellationToken cancellationToken)
{
Scheduler = await schedulerFactory.GetScheduler();
Scheduler.JobFactory = jobFactory;
foreach (var j in jobMetadatas) {
var job = CreateJob(j);
var trigger = CreateTrigger(j);
await Scheduler.ScheduleJob(job, trigger, cancellationToken);
}
await Scheduler.Start(cancellationToken);
}
public async Task StopAsync(CancellationToken cancellationToken)
{
await Scheduler?.Shutdown(cancellationToken);
}
private ITrigger CreateTrigger(JobMetadata jobMetadata)
{
return TriggerBuilder.Create()
.WithIdentity(jobMetadata.JobId.ToString())
.WithCronSchedule(jobMetadata.CronExpression)
.WithDescription($"{jobMetadata.JobName}")
.Build();
}
private IJobDetail CreateJob(JobMetadata jobMetadata)
{
return JobBuilder
.Create(jobMetadata.JobType)
.WithIdentity(jobMetadata.JobId.ToString())
.WithDescription($"{jobMetadata.JobName}")
.Build();
}
}
Add List<JobMetadata> in startup(I test with every 3 second):
JobMetadata j1 = new JobMetadata(Guid.NewGuid(), typeof(Job1), "Job1 Defination", "0/3 * * ? * * *");//Every 3 seconds
JobMetadata j2 = new JobMetadata(Guid.NewGuid(), typeof(Job2), "Job2 Defination", "0/3 * * ? * * *");//Every 3 seconds
services.AddSingleton(new List<JobMetadata> { j1,j2});
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

