Windows服务中的Quartz Job Scheduler

时间:2014-07-08 09:31:19

标签: c# .net windows-services scheduler quartz.net

我有这个Windows服务项目,OnStart方法看起来像这样

protect void OnStart(string[] args)
{
    IScheduler someScheduler = _schedFactory.GetScheduler(); // _schedFactory is a priva field of the service class

    IJobDetail someJob = JobBuilder.Create<SomeJob>()
        .WithIdentity("SomeJob")
        .Build();

    ITrigger someTrigger = TriggerBuilder.Create()
        .StartAt(new DateTimeOffset(DateTime.UtcNow.AddSeconds(30)))
        .WithSimpleSchedule(schedule => scheduler.WithIntervalInMinutes(3).RepeatForever())
        .Build();

    someScheduler.SchedulerJob(someJob, someTrigger);

    someScheduler.Start();
}

我使用Visual Studio Developer命令提示符来安装该服务。命令为installutil.exe。现在当安装该服务时,我转到任务管理器并启动它。 Thread.Sleep(10000)方法顶部有OnStart,因此我可以设法使用调试器附加到服务。因此,当它附加时我会通过代码,没有什么特别的事情发生,我的意思是没有异常发生。我甚至看到应该执行工作的时间和正确的时间。当我坐在调试模式并等待作业Execute方法执行时,它没有。我的意思是,到时候,visual studio正在加载符号,但作业本身并没有被执行。可能是什么问题?还有一件事我在这个OnStart方法中创造了两个工作。这段代码是一样的。它可能是问题的原因吗?有时第二份工作有时不会执行。我的意思是,如果它在每3分钟后执行一次就会执行,但如果它没有在第一个预定时间执行,它就永远不会执行。

1 个答案:

答案 0 :(得分:2)

代码的问题在于OnStart完成运行后对调度程序的引用超出了范围。应该在函数之外的某处定义SomeScheduler,以便它不会被垃圾收集。例如,Quartz.Net服务器项目就是这样做的(使用Topshelf,但我认为你明白了。这是安装服务的主程序。注意它返回对服务器的引用,以便主机可以保留对它的引用。

public static class Program
{
    /// <summary>
    /// Main.
    /// </summary>
    public static void Main()
    {
        HostFactory.Run(x =>
                            {
                                x.RunAsLocalSystem();

                                x.SetDescription(Configuration.ServiceDescription);
                                x.SetDisplayName(Configuration.ServiceDisplayName);
                                x.SetServiceName(Configuration.ServiceName);

                                x.Service(factory =>
                                              {
                                                  QuartzServer server = new QuartzServer();
                                                  server.Initialize();
                                                  return server;
                                              });
                            });
    }
}

在QuartzServer类中,调度程序是一个实例变量:

public class QuartzServer : ServiceControl, IQuartzServer
{
    private readonly ILog logger;
    private ISchedulerFactory schedulerFactory;
    private IScheduler scheduler; // code snipped....

}

正如@granadaCoder所指出的,简单地重复使用提供的服务器可能更容易。

以下是QuartzServerProgram.cs

的链接