asp.net-mvc-4 - Quartz.NET 触发器不触发,MVC4

标签 asp.net-mvc-4 quartz.net

我有一个使用 Unity 依赖注入(inject)的 3 层架构上的 MVC4 .Net Web 应用程序,我想每天进行一次验证并发送一些邮件。为此,我想在 Application_start 中使用 Quartz Scheduler,因为依赖注入(inject) windows 服务不是一个好的选择。

这是我在 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);

这是我的工作代码:
 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.
      }
  }
}    

但是我的工作从未执行,可能是什么问题?

最佳答案

Quartz.net 调度程序必须创建为 singleton .

您可以安装Unity.MVC4 NuGet 包。
它将创建一个 Bootstrap 应该看起来像这样的类:

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

然后你必须创建自己的 的实现。招聘工厂 .这个article可能会帮助你和this one值得一读:
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);
    }
}

回到您的 Unity Bootstrap 你必须注册你的接口(interface):
    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;
    }

我已经将我的服务调度程序封装在一个类中,以便我可以创建它单例:
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);
    }
}

正如您在本类(class)中所看到的,我将创建我的作业/触发器并启动调度程序。

现在在您的申请_开始 (global.asax) 您可以“引导”您的 Unity 容器,获取服务调度程序并运行它。
var unityContainer = Infrastructure.Bootstrapper.Initialise();
unityContainer.Resolve<IQuartzScheduler>().Run();

您可以在此 link 之后找到工作示例( QuartzWithUnity )。

关于asp.net-mvc-4 - Quartz.NET 触发器不触发,MVC4,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17740048/

相关文章:

c# - 将 html/css 模板转换为 asp.net mvc 4

c# - Razor 显示属性名称而不是值

c# - 从 ASP.Net MVC 4 中的 Kendo UI MultiSelect 获取 PrimaryId

c# - Quartz.Net 初始化项目

quartz.net - 从 ASP.Net 应用程序检索 Quartz.net 作业信息

asp.net-mvc - 如何在我的 asp.net mvc View 中显示来自 webclient 的响应(html)

javascript - 在c# mvc中将html代码作为javaScript中的字符串传递

c# - Simple Injector 中的异步工厂

quartz-scheduler - quartz : Show trigger interval/schedule details

c# - quartz 调度器 : How to pass custom objects as JobParameter?