4

我正在尝试在 ASP.NET MVC 4 应用程序中使用 Quartz.net 2.0 安排任务,但我无法执行任务。

这是代码:

public class ScheduleTaskConfig
{
    public static void StartScheduler()
    {
        ISchedulerFactory schedulerFactory = new StdSchedulerFactory();

        IScheduler scheduler = schedulerFactory.GetScheduler();

        JobKey emailSenderTaskKey = new JobKey("emailSenderTask", "email");
        IJobDetail emailSenderTask = JobBuilder.Create<QueuedEmailsSendTask>()
            .WithIdentity(emailSenderTaskKey)
            .Build();

        TriggerKey emailSenderTriggerKey = new TriggerKey("emailSenderTrigger", "email");
        ITrigger emailSenderTrigger = TriggerBuilder.Create()
            .WithIdentity(emailSenderTriggerKey)
            .WithSimpleSchedule(s => s.RepeatForever().WithIntervalInSeconds(5))
            .StartNow()
            .Build();

        scheduler.ScheduleJob(emailSenderTask, emailSenderTrigger);
        scheduler.Start();
    }
}

它在 global.asax 应用程序启动中调用

protected void Application_Start()
{
    ScheduleTaskConfig.StartScheduler();
    ...
}

这是实现 IJob 接口的类:

public class QueuedEmailsSendTask : IJob
{
    private IQueuedEmailsService _queuedEmailsService { get; set; }
    private IEmailSenderService _emailSenderService { get; set; }

    public QueuedEmailsSendTask(IQueuedEmailsService queuedEmailsService, IEmailSenderService emailSenderService)
    {
        this._queuedEmailsService = queuedEmailsService;
        this._emailSenderService = emailSenderService;
    }

    public void Execute(IJobExecutionContext executeContext)
    {
        //do stuff ...
    }
}

我在 Execute 方法的开头放置了一个断点,但调试器并没有停在那里。我究竟做错了什么?

更新: 它与实现没有默认构造函数的 IJob 接口的类有关。如果我像这样修改构造函数,它会起作用:

public QueuedEmailsSendTask()
{
}

但我需要能够注入我的依赖项。我正在使用 Autofac IoC 容器。

4

3 回答 3

7

要使 Quartz.net 与 IoC 容器一起工作,您需要有一个实现 IJobFactory 的工厂类:

public class AutofacJobFactory : IJobFactory
{
    private readonly IContainer _container;

    public AutofacJobFactory(IContainer container)
    {
        _container = container;
    }

    public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
    {
        return (IJob)_container.Resolve(bundle.JobDetail.JobType);
    }
}

然后需要在初始化代码中将 JobFactory 实例分配给调度程序:

ISchedulerFactory schedulerFactory = new StdSchedulerFactory();
IScheduler scheduler = schedulerFactory.GetScheduler();
scheduler.JobFactory = new AutofacJobFactory(container);

并且不要忘记在 IoC 容器中注册作业。

于 2013-05-21T06:57:04.857 回答
1

您是否尝试在启动调度程序后安排作业?

public class ScheduleTaskConfig
{
    public static void StartScheduler()
    {
        ISchedulerFactory schedulerFactory = new StdSchedulerFactory();

        IScheduler scheduler = schedulerFactory.GetScheduler();
        scheduler.Start(); //start here   

        //construct job info

        scheduler.ScheduleJob(emailSenderTask, emailSenderTrigger); //schedule here
    }
}
于 2013-05-20T20:09:56.167 回答
0

您需要确保AutofacJobFactory负责实例化作业。这意味着不使用该JobBuilder对象。 相反,您应该以对象AutofacJobFactory的形式传递调度程序要创建的作业的详细信息。JobDetailImpl您的工作代码如下所示。

ISchedulerFactory schedulerFactory = new StdSchedulerFactory();

IScheduler scheduler = schedulerFactory.GetScheduler();
scheduler.JobFactory = new AutofacJobFactory(container);
scheduler.Start(); //start here  

// construct job info
JobDetailImpl jobDetail = new JobDetailImpl("emailSenderTask", null, typeof(QueuedEmailsSendTask));

TriggerKey emailSenderTriggerKey = new TriggerKey("emailSenderTrigger", "email");
ITrigger emailSenderTrigger = TriggerBuilder.Create()
    .WithIdentity(emailSenderTriggerKey)
    .WithSimpleSchedule(s => s.RepeatForever().WithIntervalInSeconds(5))
    .StartNow()
    .Build();

sched.ScheduleJob(jobDetail, trigger);

有关完整示例,请参阅以下问题How do I create a Quartz.NET's job requires injection with autofac

于 2013-06-04T04:15:26.377 回答