我有这个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分钟后执行一次就会执行,但如果它没有在第一个预定时间执行,它就永远不会执行。
答案 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所指出的,简单地重复使用提供的服务器可能更容易。
的链接