Quartz Scheduler 作业有时不起作用。永远只工作一个
Quartz Scheduler jobs dont work same times. Allsways work only one
问题:我的作业不能同时工作。总是只工作一个。代码有什么问题。
程序运行如下:
预期运行次数
**信息:exampleProject.Api.Services.QuartzServices.Job1[0]
Job1 正在工作...
信息:exampleProject.Api.Services.QuartzServices.Job2[0]
Job2 正在工作...**
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) { }
}
工作元数据
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;
}
}
工作 1
[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...");
}
}
工作2
[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>();
这是一个工作演示:
将 JobMetadata jobMetadata 更改为 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();
}
}
在启动时添加List<JobMetadata>
(我每3秒测试一次):
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});
结果:
问题:我的作业不能同时工作。总是只工作一个。代码有什么问题。
程序运行如下:
预期运行次数
**信息:exampleProject.Api.Services.QuartzServices.Job1[0] Job1 正在工作...
信息:exampleProject.Api.Services.QuartzServices.Job2[0] Job2 正在工作...**
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) { }
}
工作元数据
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;
}
}
工作 1
[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...");
}
}
工作2
[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>();
这是一个工作演示:
将 JobMetadata jobMetadata 更改为 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();
}
}
在启动时添加List<JobMetadata>
(我每3秒测试一次):
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});
结果: