问题
I am trying to schedule a task using Quartz.net 2.0 in ASP.NET MVC 4 application, but i can not get the task to be executed.
Here is the code:
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();
}
}
It is called in global.asax application start
protected void Application_Start()
{
ScheduleTaskConfig.StartScheduler();
...
}
And here is the class that implements the IJob interface:
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 ...
}
}
I placed a breakpoint at the beginning of the Execute method, but the debugger does not stop there. What am i doing wrong?
UPDATE: It has something to do with the class that implements the IJob interface not having a default constructor. It works, if I modify the constructor like this:
public QueuedEmailsSendTask()
{
}
But I need to be able to inject my dependencies. I am using the Autofac IoC container.
回答1:
To make Quartz.net work with an IoC container you need to have a factory class implementing 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);
}
}
The JobFactory instance then needs to be assigned to the scheduler in the initialization code:
ISchedulerFactory schedulerFactory = new StdSchedulerFactory();
IScheduler scheduler = schedulerFactory.GetScheduler();
scheduler.JobFactory = new AutofacJobFactory(container);
And don't forget to register the job in the IoC container.
回答2:
Have you tried scheduling the job after starting the scheduler?
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
}
}
回答3:
You need to ensure that the AutofacJobFactory
is responsible for instantiating the job. This means not using the JobBuilder
object. Instead you should pass the details of the job to be created by the scheduler's AutofacJobFactory
in the form of a JobDetailImpl
object. Your working code would look something like the following.
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);
For a complete example, please see the following question How do I create a Quartz.NET’s job requiring injection with autofac
来源:https://stackoverflow.com/questions/16653178/how-to-schedule-task-using-quartz-net-2-0