设置 Quartz.NET 触发器以在特定对象实例上触发

发布于 2024-10-19 10:32:03 字数 567 浏览 5 评论 0原文

我怎样才能让 Quartz 在已经创建的对象上触发触发器?初始化对象?

例如,

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 在实例化作业并运行它时遇到问题。有什么方法可以让 Quartz 触发 Foo, f 的实例吗?

如果我遗漏了有关 Quartz 及其用法的基本事实,请原谅我。

How can I get Quartz to fire a trigger on an already created & initialized object?

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();

As foo doesn't have a 0 args constructor Quartz.NET is having issues instantiating the Job and running it. Is there any way I can get Quartz to trigger the instance of Foo, f?

Please forgive me if I'm missing a fundamental fact about Quartz and its usage.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

泼猴你往哪里跑 2024-10-26 10:32:03

您可以实现自己的 Quartz.Spi.IJobFactory (使用 DI 容器)来定义作业的执行方式创建并初始化。 Quartz 不允许调度已经初始化的作业。

这里的 JobFactory 使用 unity 来创建作业。在容器中,您可以注册作业类型并定义容器应如何构建作业以及如何解决作业的依赖关系。

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);
        }
    }
}

You could implement your own Quartz.Spi.IJobFactory (that uses an DI container) to define how jobs are created and initialized. Quartz does not allow to schedule already initialized job.

Here´s a JobFactory that uses unity to create jobs. In the container you could register the job type and define how the container should construct the job and how to resolve dependencies of the job.

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);
        }
    }
}
何处潇湘 2024-10-26 10:32:03

Quartz.NET 文档指出:(文字非常小!)

调度程序每次执行作业时,都会在调用其 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 规则,但这至少意味着我可以做需要做的事!

The Quartz.NET documentation states: ( In very small writing!)

Each (and every) time the scheduler executes the job, it creates a new instance of the class before calling its Execute(..) method. One of the ramifications of this behavior is the fact that jobs must have a no-arguement constructor.

So having Jobs with complex constructors is a no-no!

Time for Plan B:

I created one 'Master' Job. This job looked in the context.JobDetail.JobDataMap to determine which type of task really should be executed. The Execute function looked a little like:

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();
    }           
}

This allows the Task to be created prior to the scheduling and the task instance to be run whenever the Master Task Fires e.g.

JobDetail detail = new JobDetail( "foo", null, typeof( MasterTask) );
detail.JobDataMap["Task"] = task;

I'm sure this violates some master Quartz rule, but it at least means I can do what needs to be done!

爱,才寂寞 2024-10-26 10:32:03

不要在实现 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

Don't put anything in the class implementing IJob, create a class that implement a IJobListener and make it listen to the job of your group.

var myJobListener = new YourClassImplementingIJobListener(param1, param2);
sched.ListenerManager.AddJobListener(myJobListener,GroupMatcher<JobKey>.GroupEquals("myJobGroup"));

More info on this here
http://www.quartz-scheduler.net/documentation/quartz-2.x/tutorial/trigger-and-job-listeners.html

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文