Quartz.NET触发不火,MVC4 [英] Quartz.NET trigger does not fire, MVC4

查看:188
本文介绍了Quartz.NET触发不火,MVC4的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个统一的依赖注入的3层架构的MVC4 .NET Web应用程序,我想每天shedule一个verficiation和发送邮件的一些是在哪里的情况。为此,我想使用Quartz调度中的Application_Start,因为依赖注入窗口的服务是不是一个好的选择。

I have a MVC4 .Net web application on 3-tier architecture with Unity dependency injection, and I want to shedule everyday a verficiation and send some mails where is the case. For this I want to use Quartz Scheduler in Application_start, because of the dependency injection windows service is not a good option.

下面是我的Application_Start code。

Here is my code in application_start.

        // construct a scheduler factory
        ISchedulerFactory schedFact = new StdSchedulerFactory();
        IScheduler sched = schedFact.GetScheduler();
        sched.Start();

        IJobDetail dailyUserMailJob = new JobDetailImpl("DailyUserMailJob", null, typeof(SchedulerJob));
        // fire every time I open App/EveryDay
        ITrigger dailyUserMailTrigger = new SimpleTriggerImpl("DailyUserMailTrigger", 1,
                                                 new TimeSpan(1, 0, 0, 0));
        sched.ScheduleJob(dailyUserMailJob, dailyUserMailTrigger);

下面是我的工作code:

Here is my job code :

 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Web;
 using EvaluationMvc.Bll.Contracts;
 using Quartz;
 using Quartz.Impl;

namespace EvaluationMvc.Utils
{
   public class SchedulerJob : IJob
   { 
      private IEvaluationBus _iEvaluationBus;

      public SchedulerJob(IEvaluationBus iEvaluationBus)
      {
        //Dependency injection
          _iEvaluationBus = iEvaluationBus; 

      }
      public void Execute(IJobExecutionContext context)
      {
        _iEvaluationBus.testingArchitecture();
       // Sends a test mail.
      }
  }
}    

不过我的工作永远不会执行,可能是什么问题?

However my job is never executed, what could be the problem ?

推荐答案

Quartz.net计划必须创建为

Quartz.net Scheduler must be created as singleton.

您可以安装 Unity.MVC4 的NuGet包。结果
这将创建一个引导程序类应该是这个样子:

You can install Unity.MVC4 NuGet Package.
It will create a Bootstrapper class which should look something like this:

public static class Bootstrapper
{
    public static IUnityContainer Initialise()
    {
        var container = BuildUnityContainer();
        DependencyResolver.SetResolver(new UnityDependencyResolver(container));
        return container;
    }

    private static IUnityContainer BuildUnityContainer()
    {
        var container = new UnityContainer();
        // Register your interfaces here. 
        RegisterTypes(container);
        return container;
    }

    public static void RegisterTypes(IUnityContainer container)
    {
    }
}

然后,你必须创建自己的实施的JobFactory 。这文章可以帮助你和这个是值得一读:

Then you have to create your own implementation of JobFactory. This article might help you and this one is worth reading:

public class UnityJobFactory: IJobFactory
{
    private readonly IUnityContainer container;

    static UnityJobFactory()
    {
    }

    public UnityJobFactory(IUnityContainer container)
    {
        this.container = container;
    }

    public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
    {
        var jobDetail = bundle.JobDetail;
        var jobType = jobDetail.JobType;

        try
        {
            return this.container.Resolve(jobType) as IJob;
        }
        catch (Exception ex)
        {
            throw new SchedulerException(string.Format(
                CultureInfo.InvariantCulture,
                "Cannot instantiate class '{0}'", new object[] { jobDetail.JobType.FullName }), ex);
        }
    }

    public void ReturnJob(IJob job)
    {
        // Nothing here. Unity does not maintain a handle to container created instances.
    }
}

和自己实施的 StdSchedulerFactory

public class UnitySchedulerFactory : StdSchedulerFactory
{
    private readonly UnityJobFactory unityJobFactory;

    public UnitySchedulerFactory(UnityJobFactory unityJobFactory)
    {
        this.unityJobFactory = unityJobFactory;
    }

    protected override IScheduler Instantiate(QuartzSchedulerResources rsrcs, QuartzScheduler qs)
    {
        qs.JobFactory = this.unityJobFactory;
        return base.Instantiate(rsrcs, qs);
    }
}

让我们再回到您的统一引导程序你必须注册接口:

    private static IUnityContainer BuildUnityContainer()
    {
        var container = new UnityContainer();

        container.RegisterType<ISchedulerFactory, UnitySchedulerFactory>(new ContainerControlledLifetimeManager());
        container.RegisterType<IScheduler>(new InjectionFactory(c => c.Resolve<ISchedulerFactory>().GetScheduler()));
        container.RegisterType<IQuartzScheduler, QuartzScheduler>(new ContainerControlledLifetimeManager());
        container.RegisterType<IEvaluationBus, EvaluationBus>();

        RegisterTypes(container);

        return container;
    }

我已经结束了我的服务调度中的一类,这样我可以单创建它:

I've wrapped up my service scheduler in a class so that I can create it singleton:

public interface IQuartzScheduler
{
    void Run();
    void Stop();
}

public class QuartzScheduler : IQuartzScheduler
{
    private readonly ISchedulerFactory SchedulerFactory;
    private readonly IScheduler Scheduler;

    public QuartzScheduler(ISchedulerFactory schedulerFactory, IScheduler scheduler)
    {
        this.SchedulerFactory = schedulerFactory;
        this.Scheduler = scheduler;
    }

    public void Run()
    {
        IJobDetail dailyUserMailJob = new JobDetailImpl("DailyUserMailJob", null, typeof(Scheduler.SchedulerJob));
        // fire every time I open App/EveryDay
        ITrigger dailyUserMailTrigger = new SimpleTriggerImpl("DailyUserMailTrigger", 10,
                                                 new TimeSpan(0, 0, 0, 20));

        this.Scheduler.ScheduleJob(dailyUserMailJob, dailyUserMailTrigger);

        this.Scheduler.Start();
    }

    public void Stop()
    {
        this.Scheduler.Shutdown(false);
    }
}

正如你在这个班,我会创造我的工作/触发和启动调度程序见。

As you can see in this class I'll create my jobs/trigger and start the scheduler.

现在在的Application_Start (Global.asax中),您可以引导的团结容器,得到最好的服务调度和运行它。

now in your Application_Start (global.asax) you can "bootstrap" your Unity Container, get the service scheduler and run it.

var unityContainer = Infrastructure.Bootstrapper.Initialise();
unityContainer.Resolve<IQuartzScheduler>().Run();

您可以找到以下这个链接工作示例( QuartzWithUnity )。

You can find a working sample following this link (QuartzWithUnity).

这篇关于Quartz.NET触发不火,MVC4的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆