我有Windows服务。该服务具有静态变量,这些变量记录服务的开始时间和经过的时间(每15秒)。
服务开始时间是在服务的构造函数中设置的,经过的时间记录在OnTimer()
。
OnStart()
和OnStop()
被编程为将时间记录到日志文件中。 Self Host Web API嵌入在服务中,以报告服务变量的值。
使用服务管理器启动和停止服务时,启动或停止消息已成功记录在日志文件中。
我的问题是关闭系统并重新启动时,没有记录服务停止和启动消息。
我确实将CanStop
和CanShutdown
设置为true。
似乎在系统关闭时服务并未停止。可以通过检查日志文件来证明没有服务停止和启动记录被记录。同样,在运行Web API时,它显示开始时间和经过时间与上次服务启动时保持相同。
所以,为什么服务的变量在系统重新启动后仍保持活动状态,我以为它们在内存中运行,但并不能显示。
有人有想法吗?谢谢。
经过一些尝试,我发现,在重新引导系统时,记录了服务停止和启动消息,Web api可以返回新的时间值。但是,当SHUTDOWN并再次打开时,没有停止和开始消息记录,Web api将返回旧的上次服务开始时间值。
所以,我的新问题是,如果服务在关闭时没有停止,那么在系统启动时是否需要再次调用服务的构造函数?我是Windows Service的新手,如果答案是否定的,这是令人惊讶的。
public partial class TimeGoesBy : ServiceBase
{
private Logger _logger;
private static int _mainTaskInterval;
private Timer timer;
private static DateTime tmStartTime;
private static TimeSpan tmElapsedTime;
private string baseAddress;
private static IDisposable _webapp;
private static GameOneWorld _world;
public TimeGoesBy() : this(LogManager.GetCurrentClassLogger())
{
InitializeComponent();
}
public TimeGoesBy(Logger logger, int mainTaskInterval = 15000) : base()
{
InitializeComponent();
this.CanShutdown = true;
this.CanStop = true;
tmStartTime = DateTime.Now;
this._logger = logger;
_mainTaskInterval = mainTaskInterval;
int interval;
if (!String.IsNullOrEmpty(ConfigurationManager.AppSettings["TaskInterval"]))
{
if (Int32.TryParse(ConfigurationManager.AppSettings["TaskInterval"], out interval))
{
_mainTaskInterval = interval;
}
}
baseAddress = "http://" +
(String.IsNullOrEmpty(ConfigurationManager.AppSettings["WebApiUrl"].ToString()) ? "" : ConfigurationManager.AppSettings["WebApiUrl"].ToString()) +
(String.IsNullOrEmpty(ConfigurationManager.AppSettings["WebApiIpPort"].ToString()) ? "/" : ":" + ConfigurationManager.AppSettings["WebApiIpPort"].ToString() + "/");
// Start OWIN host
_webapp = WebApp.Start<Startup>(url: baseAddress);
_logger.Info("Web API start at " + baseAddress);
}
protected override void OnStart(string[] args)
{
// set interval by service parameters
if (args != null && args.Length > 0)
{
int intervalParameter;
if (int.TryParse(args[0], out intervalParameter))
{ _mainTaskInterval = intervalParameter; }
}
// Setup timer
timer = new Timer();
timer.Interval = _mainTaskInterval;
timer.Elapsed += new System.Timers.ElapsedEventHandler(this.OnTimer);
timer.Start();
_logger.Info("Start service...");
base.OnStart(args);
}
protected override void OnStop()
{
_webapp?.Dispose();
timer.Stop();
_logger.Info("Stop service.");
base.OnStop();
}
protected override void OnShutdown()
{
this.Stop();
base.OnShutdown();
}
protected void OnTimer(object sender, System.Timers.ElapsedEventArgs args)
{
try
{
MainTask();
}
catch (Exception ex)
{
_logger.Error(ex, "Main task exception");
}
}
protected virtual void MainTask()
{
tmElapsedTime = DateTime.Now.Subtract(tmStartTime);
}
}
Why the Windows Service not call the OnStart method?
在研究了上面的链接之后,我意识到窍门是Windows快速启动功能。通过关闭该选项,关机也可以按预期记录服务停止/启动。 Web API也报告正确的值。