问题
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.
回答1:
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
来源:https://stackoverflow.com/questions/24628372/quartz-job-scheduler-in-windows-service