Служба Windows .NET прервана во время выключения системы - PullRequest
1 голос
/ 15 февраля 2010

Моя служба Windows - это сервер данных с большим объемом кэша. Во время обслуживания OnStop я сохраняю кеш, чтобы данные не терялись. Сохранение кэша может занять несколько минут, поэтому для предотвращения тайм-аута диспетчера служб Windows я использую обратный вызов SetServiceStatus Win32:

this.serviceStatus.currentState = (int)State.SERVICE_STOP_PENDING;
this.serviceStatus.checkPoint = 1;
this.serviceStatus.waitHint = 60000;
SetServiceStatus(Process.GetCurrentProcess().Handle, ref this.serviceStatus);

Это прекрасно работает.

Я также установил для CanShutdown значение true и добавил OnShutdown, чтобы служба была защищена от отключения системы. Здесь я фактически делаю то же самое, что и в OnStop:

protected override void OnShutdown()
{
    this.OnStop(); 
    base.OnShutdown();
}

Это не слишком хорошо работает. Когда система выключается, когда кеш сохраняется, я получаю «Устройство не готово». Это говорит о том, что Windows прерывает службу, прежде чем она будет остановлена ​​/ выключена. Предотвращение этого с SetServiceStatus, по-видимому, не работает.

Как мне получить больше времени (задержка перезагрузки), чтобы выполнить сохранение?

Любые предложения приветствуются.

Ответы [ 4 ]

2 голосов
/ 02 февраля 2011

Предпочтительный способ справиться с этим можно найти в этой статье в блоге команды BCL . В этой статье содержится небольшая справочная информация о том, как управляемые службы взаимодействуют с SCM, что важно для понимания того, почему подход, показанный в этом вопросе, больше не рекомендуется.

Проще говоря, ServiceBase теперь обрабатывает управление состоянием службы для вас, и вашему коду просто нужно запросить дополнительное время, если требуется. Прочитайте статью, чтобы найти несколько других хороших рекомендаций по написанию SCM-дружественных сервисов в .NET.

0 голосов
/ 14 марта 2012

Другой простой способ, после нескольких часов поиска о том, как включить метод setservicestatus:

    protected override void OnStop()
    {
        stopTimer();
        m_run = false;
        while (m_queue.Count > 0)
            Thread.Sleep(500);
    }
0 голосов
/ 17 февраля 2010

После некоторого тестирования кажется, что это была проблема с системой, а не с моим сервисом.

0 голосов
/ 15 февраля 2010

Использование ManualResetEvent может быть уловкой.

...