简体   繁体   中英

Quartz Job Scheduler in Windows Service

I have this windows service project which's OnStart method looks like this

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();
}

I use Visual Studio Developer Command Prompt to install the service. The command is installutil.exe . now when the service is install then I go to task manager and start it. there is Thread.Sleep(10000) in the top of the OnStart method so I could manage to attach to the service with the debugger. So when it's attached I go through the code, nothing special happens, I mean no exception happens. I even see the time when the job should be executed and its correct. while I am sitting in a debug mode and waiting for job's Execute method to get executed, it does not. I mean when the time comes visual studio is loading symbols but the job itself does not get executed. What can be the problem? and one more thing I am creating two jobs in this OnStart method. the code for that is the same. Can it be the cause of the problem ? The second job sometimes get executed sometimes not. I mean if it executes once it will execute after every 3 minute but if it does not executed at the first scheduled time, it never executes.

The problem with your code is that the reference to the scheduler falls out of scope after OnStart finishes running. SomeScheduler should be defined somewhere outside of the function so that it doesn't get garbage collected. As an example, this is how the Quartz.Net server project does it (using Topshelf but I think you get the idea. This is the main program, that installs the service. Notice it returns a reference to the server so the host can keep a reference to it.

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

In the QuartzServer class the scheduler is an instance variable:

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

}

As @granadaCoder points out, it might be easier to simply re-use the server that is provided.

Here are links to QuartzServer and Program.cs

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM