如何让Quartz触发已经创建的&初始化对象?
e.g。
public class Foo : IJob
{
public Foo ( configuration items ... ) { }
}
// Calling Code...
Foo f = new Foo( /*Non empty constructor*/ );
Schedular sched = new SchedulerFactory().GetScheduler();
JobDetail jD = new JobDetail("fooDetail", null typeof(Foo));
Trigger trig = TriggerUtils.MakeSecondlyTrigger(15);
sched.ScheduleJob( jD, trig );
sched.Start();
由于foo没有0 args构造函数,Quartz.NET在实例化Job并运行它时遇到问题。有什么方法可以让Quartz触发Foo的实例,f?
如果我错过了有关Quartz及其用法的基本事实,请原谅我。
答案 0 :(得分:3)
您可以实现自己的Quartz.Spi.IJobFactory(使用DI容器)来定义作业的创建和初始化方式。 Quartz不允许安排已经初始化的作业。
这是一个使用unity创建作业的JobFactory。在容器中,您可以注册作业类型并定义容器应如何构造作业以及如何解决作业的依赖关系。
public class UnityJobFactory : IJobFactory {
public UnityJobFactory(IUnityContainer container) {
Container = container;
}
public IUnityContainer Container { get; private set; }
public IJob NewJob(TriggerFiredBundle bundle) {
try {
return Container.Resolve(bundle.JobDetail.JobType, null) as IJob;
}
catch (Exception exception) {
throw new SchedulerException("Error on creation of new job", exception);
}
}
}
答案 1 :(得分:0)
Quartz.NET documentation州:(写得很小!)
调度程序执行作业的每个(和每个)时间,它在调用其Execute(..)方法之前创建该类的新实例。这种行为的一个后果是,工作必须有一个无争议的构造函数。
因此,拥有复杂构造函数的Jobs是一个禁忌!
B计划的时间:
我创造了一个'主'工作。这个工作查看了context.JobDetail.JobDataMap,以确定应该执行哪种类型的任务 。执行功能看起来有点像:
public void Execute( JobExecutionContext context )
{
JobDataMap dataMap = context.JobDetail.JobDataMap;
// Execute the stored Task
Foo taskToExecute = dataMap["Task"] as Foo;
if ( taskToExecute != null )
{
taskToExecute.Execute();
}
}
这允许在调度之前创建任务,并且每当主任务触发时运行任务实例,例如
JobDetail detail = new JobDetail( "foo", null, typeof( MasterTask) );
detail.JobDataMap["Task"] = task;
我确信这违反了一些主要的Quartz规则,但至少意味着我可以做我们需要做的事情!
答案 2 :(得分:0)
不要在实现IJob的类中放置任何东西,创建一个实现IJobListener的类,并让它听取你的小组的工作。
var myJobListener = new YourClassImplementingIJobListener(param1, param2);
sched.ListenerManager.AddJobListener(myJobListener,GroupMatcher<JobKey>.GroupEquals("myJobGroup"));
此处有关于此的更多信息 http://www.quartz-scheduler.net/documentation/quartz-2.x/tutorial/trigger-and-job-listeners.html