【问题标题】:Shutdown Behaviours of Windows Service and the Life of VariablesWindows 服务的关闭行为和变量的生命周期
【发布时间】:2023-03-17 21:35:01
【问题描述】:

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

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

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

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

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

我确实将CanStopCanShutdown 设置为true。

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

那么,为什么服务的变量在系统重新启动后仍然存在,我以为它们在内存中运行,但它告诉我们没有。

有人有想法吗?谢谢。


经过一些尝试,我发现,当REBOOT系统时,记录服务停止和启动消息,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);
        }
    }

【问题讨论】:

  • 请分享您的代码
  • 有人试过了,结果和上面说的一样吗?

标签: .net windows-services


【解决方案1】:

Why the Windows Service not call the OnStart method?

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-06
    • 1970-01-01
    相关资源
    最近更新 更多