0

我有一个 Windows 服务。该服务具有记录服务开始时间和经过时间(每 15 秒)的静态变量。

服务的开始时间在服务的构造函数中设置,经过的时间记录在OnTimer().

OnStart()OnStop()编程为将时间记录到日志文件中。Self Host Web API 嵌入在服务中,用于报告服务变量的值。

使用服务管理器启动和停止服务时,启动或停止消息成功记录在日志文件中。

我的问题是关闭系统并重新启动时,没有记录服务停止和启动消息。

我确实将CanStopand设置CanShutdown为true。

系统关闭时似乎没有停止服务。这可以通过检查没有记录服务停止和启动记录的日志文件来证明。此外,当运行 Web API 时,它显示启动时间以及经过的时间与上次服务启动时保持相同。

那么,为什么服务的变量在系统重新启动后仍然存在,我以为它们在内存中运行,但事实并非如此。

有人有想法吗?谢谢。


经过一些尝试,我发现,当 REBOOT 系统时,记录了服务停止和启动消息,web api 可以返回新的时间值。但是,当 SHUTDOWN 并再次打开时,没有记录停止和启动消息,web api 将返回旧的上次服务启动时间值。

所以,我的新问题是,如果服务在关机时没有停止,那么在系统启动时是否需要再次调用服务的构造函数?我是 Windows 服务的新手,如果答案是否定的,那就令人惊讶了。

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

1 回答 1

0

为什么 Windows 服务不调用 OnStart 方法?

在研究了上面的链接之后,我意识到诀窍是 Windows 快速启动功能。通过关闭该选项,SHUTDOWN 还可以按预期记录服务停止/启动。Web API 还报告了正确的值。

于 2020-04-23T15:14:40.890 回答