Поведение при отключении Windows службы и срок службы переменных - PullRequest
0 голосов
/ 19 апреля 2020

У меня есть Windows Сервис. Служба имеет постоянные переменные c, которые записывают время запуска службы и истекшее время (каждые 15 секунд).

Время запуска службы задается в конструкторе службы, истекшее время записывается в OnTimer().

OnStart() и OnStop() запрограммированы для записи времени в файл журнала. Веб-API Self Host встроен в службу для сообщения о значении переменных службы.

При использовании диспетчера службы для запуска и остановки службы сообщение о запуске или остановке успешно регистрируется в файле журнала. .

Моя проблема заключается в том, что при выключении системы и перезагрузке не регистрируется остановка службы и сообщение о запуске.

Я установил CanStop и CanShutdown в значение true.

Кажется, что служба не была остановлена, когда система была выключена. Это можно проверить, проверив в файле журнала, что не было зарегистрировано ни одной остановки службы и начальных записей. Кроме того, при запуске веб-API, который показывает, что время запуска и, следовательно, истекшее время остались неизменными при последнем запуске службы.

Итак, почему переменные службы остались живы после перезагрузки системы, Я думал, что они работают в памяти, но это не говорит.

У кого-нибудь есть идея? Спасибо.


После некоторых попыток я обнаружил, что при перезагрузке системы регистрируются сообщения об остановке и запуске службы, веб-API может вернуть новое значение времени. Однако при выключении и повторном включении сообщения об остановке и запуске не регистрируются, веб-интерфейс возвращает старое значение времени последнего запуска службы.

Итак, мой новый вопрос: если служба не остановлена при выключении нужно ли снова вызывать конструктор службы при загрузке системы? Я новичок ie до 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);
        }
    }

1 Ответ

0 голосов
/ 23 апреля 2020

Почему сервис Windows не вызывает метод OnStart?

После изучения вышеуказанной ссылки я понял, что уловка - это функция Windows Fast Boot. Отключив эту опцию, SHUTDOWN также может регистрировать остановку / запуск службы, как и ожидалось. Веб-API также сообщает правильное значение.

...