Как я могу определить, когда безопасно обновлять службу Windows? - PullRequest
2 голосов
/ 07 июня 2019

У меня есть служба Windows, которая опрашивает базу данных и будет действовать в зависимости от найденных записей.

Я хочу настроить Azure Devops для автоматического развертывания обновления для этой службы.

Для развертывания обновления мне нужно остановить службу.

Есть ли способ узнать, может ли это прервать его обработку?

В моем конвейере выпуска с командной задачей я использую

sc stop MyService

[Обновить]

Вот мой упрощенный код

static class Program
{
    static void Main()
    {
        ServiceBase.Run(new ServiceBase[] { new Hoster() });
    }
}

  public sealed class Hoster : ServiceBase
{
    private IMyEngine _engine;
    private readonly EventHandler<EngineProgressEventArgs> _progressHandler;
    public Hoster()
    {
            _progressHandler = TrapEngineProgress;
    }

    protected override void OnStart(string[] args)
    {
        try
        {
            _engine = MyFactory.Create();
            _engine.Progress += _progressHandler;
            _engine.StartupEngine();
        }
        catch (Exception ex)
        {
            _logger.Error("OnStart failed", ex);
        }
    }

    protected override void OnStop()
    {
        if (_engine == null) return;
        _engine.Dispose();
        _engine.Progress -= _progressHandler;
        _engine = null;
    }


    private void TrapEngineProgress(object sender, EngineProgressEventArgs e)
    {
        switch (e.Type)
        {
            case ProgressType.Changed:
                Trace("Changed: " + e.Filename);
                break;
            case ProgressType.Created:
                Trace("Created: " + e.Filename);
                break;
            case ProgressType.Trace:
                Trace(e.Message);
                break;
            case ProgressType.Error:
                Error(e.Error, e.Message);
                break;
        }
    }
}

1 Ответ

3 голосов
/ 13 июня 2019

Когда вы вводите команду SC STOP, вы просто делаете запрос на остановку службы . Когда служба получает запрос, она может немедленно остановиться или дождаться завершения важных задач & mdash; все, что он хочет сделать. Ваш сервис находится под контролем.

Чтобы избежать недопустимого прерывания, «остановка рабочего процесса» вашей службы должна выглядеть следующим образом:

  1. Сделан запрос на остановку сервиса (через SC STOP, NET STOP и т. Д.)
  2. «Поток слушателя» службы получает запрос на остановку
  3. Поток устанавливает флаг, по которому была запрошена остановка, и устанавливает состояние службы в SERVICE_STOP_PENDING
  4. «Поток обработки» периодически проверяет флаг (в удобное время - вероятно, между заданиями)
  5. Если флаг установлен, цикл обработки завершается, когда это удобно
  6. И поскольку вся обработка завершена, статус службы устанавливается на SERVICE_STOPPED, и вся служба завершается.

При таком подходе ваше обслуживание никогда не будет прервано в «плохом» месте.

...