Quartz.NET调度器,在每个scheduler.Start()中初始化
Quartz.NET Scheduler, initalization in each scheduler.Start()
我有几个扩展到抽象 RobotJob
class 的机器人作业,共享日志文件、配置、pause/continue 选项等...我正在尝试采用 Quartz.NET
来安排这些作业。我还试图以最少的 code/structure 修改使其工作。但是,我有两个相互交织的问题:
1) 我需要 MyRobotJob
中的无参数构造函数,因为 scheduler.Start()
构造了一个新的 MyRobotJob
对象,但我不需要无参数构造函数。
2) 由于 scheduler.Start()
创建了一个新的 MyRobotJob
,构造函数的调用导致了无限循环。我知道这个设计有问题,我想知道如何修改它,以便只有一个 MyRobotJob
对象会 运行 根据时间表。
我尝试了什么: 我在RobotJob
中定义了一个returns IJob
的抽象方法。我在 MyRobotJob
中实现了它,它返回了另一个 class MyRobotRunner
,实现了 IJob
。但是,如果我在单独的 class 中这样做,我将无法在 RobotJob
中使用我的日志记录方法。代码的简化版本是这样的:
public abstract class RobotJob
{
public string Cron { get; set; }
public string LogFile { get; set; }
public JobStatus Status { get; set; }
// Properties, helpers...
protected RobotJob(string name, string cron, string logFile = null)
{
this.Name = name;
this.LogFile = logFile;
this.Cron = cron;
InitQuartzScheduler();
}
private void InitQuartzScheduler()
{
scheduler = StdSchedulerFactory.GetDefaultScheduler();
IJobDetail job = JobBuilder.Create(this.GetType())
.WithIdentity(this.GetType().Name, "AJob")
.Build();
trigger = TriggerBuilder.Create()
.WithIdentity(this.GetType().Name, "ATrigger")
.StartNow()
.WithCronSchedule(Cron)
.Build();
scheduler.ScheduleJob(job, trigger);
scheduler.Start(); // At this part, infinite loop starts
}
}
[DisallowConcurrentExecution]
public class MyRobotJob : RobotJob, IJob
{
// I need a parameterless constructor here, to construct
public MyRobotJob()
: base("x", "cron", "logFile")
public MyRobotJob(string name, string cron, string logFile = null)
: base(name, cron, logFile)
{
}
public override void Execute(IJobExecutionContext context)
{
// DoStuff();
}
}
您无需在每次添加工作时都调用 scheduler.Start()。在调度程序包装器上创建一个方法,该方法将添加您的作业,并且只会启动您的调度程序一次。
public class Scheduler : IScheduler
{
private readonly Quartz.IScheduler quartzScheduler;
public Scheduler()
{
ISchedulerFactory schedulerFactory = new StdSchedulerFactory();
quartzScheduler = schedulerFactory.GetScheduler();
quartzScheduler.Start();
}
public void Stop()
{
quartzScheduler.Shutdown(false);
}
public void ScheduleRoboJob()
{
// your code here
quartzScheduler.ScheduleJob(job, trigger);
}
我有几个扩展到抽象 RobotJob
class 的机器人作业,共享日志文件、配置、pause/continue 选项等...我正在尝试采用 Quartz.NET
来安排这些作业。我还试图以最少的 code/structure 修改使其工作。但是,我有两个相互交织的问题:
1) 我需要 MyRobotJob
中的无参数构造函数,因为 scheduler.Start()
构造了一个新的 MyRobotJob
对象,但我不需要无参数构造函数。
2) 由于 scheduler.Start()
创建了一个新的 MyRobotJob
,构造函数的调用导致了无限循环。我知道这个设计有问题,我想知道如何修改它,以便只有一个 MyRobotJob
对象会 运行 根据时间表。
我尝试了什么: 我在RobotJob
中定义了一个returns IJob
的抽象方法。我在 MyRobotJob
中实现了它,它返回了另一个 class MyRobotRunner
,实现了 IJob
。但是,如果我在单独的 class 中这样做,我将无法在 RobotJob
中使用我的日志记录方法。代码的简化版本是这样的:
public abstract class RobotJob
{
public string Cron { get; set; }
public string LogFile { get; set; }
public JobStatus Status { get; set; }
// Properties, helpers...
protected RobotJob(string name, string cron, string logFile = null)
{
this.Name = name;
this.LogFile = logFile;
this.Cron = cron;
InitQuartzScheduler();
}
private void InitQuartzScheduler()
{
scheduler = StdSchedulerFactory.GetDefaultScheduler();
IJobDetail job = JobBuilder.Create(this.GetType())
.WithIdentity(this.GetType().Name, "AJob")
.Build();
trigger = TriggerBuilder.Create()
.WithIdentity(this.GetType().Name, "ATrigger")
.StartNow()
.WithCronSchedule(Cron)
.Build();
scheduler.ScheduleJob(job, trigger);
scheduler.Start(); // At this part, infinite loop starts
}
}
[DisallowConcurrentExecution]
public class MyRobotJob : RobotJob, IJob
{
// I need a parameterless constructor here, to construct
public MyRobotJob()
: base("x", "cron", "logFile")
public MyRobotJob(string name, string cron, string logFile = null)
: base(name, cron, logFile)
{
}
public override void Execute(IJobExecutionContext context)
{
// DoStuff();
}
}
您无需在每次添加工作时都调用 scheduler.Start()。在调度程序包装器上创建一个方法,该方法将添加您的作业,并且只会启动您的调度程序一次。
public class Scheduler : IScheduler
{
private readonly Quartz.IScheduler quartzScheduler;
public Scheduler()
{
ISchedulerFactory schedulerFactory = new StdSchedulerFactory();
quartzScheduler = schedulerFactory.GetScheduler();
quartzScheduler.Start();
}
public void Stop()
{
quartzScheduler.Shutdown(false);
}
public void ScheduleRoboJob()
{
// your code here
quartzScheduler.ScheduleJob(job, trigger);
}