【问题标题】:Quartz Job Scheduler in Windows ServiceWindows 服务中的 Quartz 作业调度程序
【发布时间】:2014-08-28 23:38:25
【问题描述】:

我有这个 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 开发人员命令提示符来安装该服务。命令是installutil.exe。现在安装服务后,我转到任务管理器并启动它。 Thread.Sleep(10000)OnStart 方法的顶部有Thread.Sleep(10000),因此我可以设法使用调试器附加到服务。因此,当它附加时,我浏览了代码,没有什么特别的事情发生,我的意思是没有发生异常。我什至看到了应该执行作业的时间及其正确性。当我处于调试模式并等待作业的Execute 方法被执行时,它没有。我的意思是当时间到来时,视觉工作室正在加载符号,但工作本身并没有被执行。可能是什么问题?还有一件事我在这个OnStart 方法中创造了两个工作。代码是一样的。这可能是问题的原因吗?第二份工作有时会被执行,有时不会。我的意思是如果它执行一次,它将在每 3 分钟后执行一次,但如果它没有在第一个预定时间执行,它永远不会执行。

【问题讨论】:

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


    【解决方案1】:

    您的代码的问题是在 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 的链接

    【讨论】:

      最近更新 更多