Лучшая практика обработки исключений в службе Windows? - PullRequest
22 голосов
/ 01 июля 2010

В настоящее время я пишу службу Windows, которая работает полностью в фоновом режиме и что-то делает каждый день.Моя идея заключается в том, что служба должна быть очень стабильной, поэтому, если что-то пойдет не так, ее не следует останавливать, но попробуйте снова на следующий день и, конечно, зарегистрируйте исключение.Можете ли вы предложить мне наилучшую практику, как сделать действительно стабильные службы Windows?

Я прочитал статью Скотта Хансельмана об исключительной практике обработки исключений , где он пишет, что есть только несколько случаев, когда вы должны проглотить исключение.Я так или иначе думаю, что служба Windows - один из немногих случаев, но я был бы рад получить некоторое подтверждение этого.

Ответы [ 7 ]

7 голосов
/ 01 июля 2010

«Глотание» исключения отличается от «отказа от конкретной задачи без остановки всего процесса». В нашей службе Windows мы отлавливаем исключения, регистрируем их детали, затем корректно ухудшаем эту задачу и ждем следующей. Затем мы можем использовать журнал для устранения ошибки, пока сервер еще работает.

4 голосов
/ 01 июля 2010

Вопрос, который вы должны задать, заключается в том, должна ли ваша служба Windows быть отказоустойчивой.Помните, что любые необработанные исключения приведут к остановке службы, что приведет к ее немедленной недоступности.Как вы думаете, как должен вести себя ваш сервис?Должен ли он попытаться и дальше обслуживать все, что ему нужно?Должен ли он быть прекращен?

2 голосов
/ 01 июля 2010

На самом деле, если у вас есть непредвиденное исключение, которое передается полностью на верхний уровень вашего сервиса, вы должны не продолжить обработку; войти и распространить это. Если вам действительно нужен «надежный» сервис, вам понадобится «сторожевой таймер», который перезапускает исходный сервис при его выходе.

Обратите внимание, что современные операционные системы действуют как сторожевой таймер, поэтому в большинстве случаев вам не требуется сервис сторожевого таймера (откройте вкладку «Восстановление» в свойствах вашего Сервиса). Исторически сложилось так, что критически важные службы имели бы вторую службу «сторожевого таймера», единственная цель которой - перезапустить реальную службу в случае сбоя.

Похоже, ваш дизайн может использовать планировщик; просто позвольте Windows позаботиться о части «один раз в день» и просто сделайте так, чтобы ваш сервис выполнял эту задачу один раз. Если это не удается, хорошо; Windows отвечает за его повторный запуск на следующий день.

И последнее замечание: этот уровень надежности в услуге редко требуется. В коммерческом коде я видел его только в нескольких антивирусных программах и программе сетевой фильтрации (которая должна была работать, иначе вся сетевая связь потерпит неудачу). Я сам выполнил пару программ «сторожевого пса», но они предназначались для таких клиентов, как автомобильные компании, которые потеряли бы тонн денег, когда их системы сборочных линий вышли из строя. В дополнение к программному сторожу эти системы также имели резервные источники питания, жесткие диски с возможностью горячей замены RAID и полную копию всей системы для использования в качестве автоматического перехода на другой ресурс.

Просто скажу: вы, возможно, захотите пересмотреть, насколько вам действительно нужно повысить надежность (учитывая, что 100% надежность невозможна; к ней можно приблизиться только по экспоненциальной стоимости).

2 голосов
/ 01 июля 2010

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

Это различие должно сопровождаться сильным различием между структурами "супервизорной" части службы (той, которая планирует периодическое действие) и той частью службы, которая фактически делает такой периодической действие. В случае восстанавливаемого исключения вы можете прервать запущенную операцию и полностью сбросить эту последнюю часть, очевидно записав все подробности исключения в журнал системных событий; с другой стороны, если вы получили неисправимую ошибку (структуры супервизора в несогласованном состоянии и исключения SEH, конечно), вы должны просто зарегистрировать свою ошибку и выйти, так как продолжение работы в несогласованном состоянии гораздо более опасно, чем вообще не работать .

1 голос
/ 18 июня 2014

Служба никогда не должна останавливаться.Существует два класса ошибок: ошибки в самой Службе и ошибки в данных, предоставляемых Службе.Об ошибках данных следует сообщать, но не игнорировать.Эти две цели могут быть достигнуты с помощью наличия ошибок в журнале службы, путем предоставления способа передачи информации об ошибке пользователю и с помощью повторной попытки службы отказать после того, как пользователь (или программист в случае ошибки в службе)исправлено то, что привело к сбою службы (очевидно, что служба должна быть остановлена, переустановлена ​​и перезапущена в случае исправления ошибки программы).

1 голос
/ 01 июля 2010

Как и многие другие вещи в разработке программного обеспечения, "один размер подходит всем".Если вы считаете целесообразным проглотить исключение с намерением повторить попытку позднее, это вполне разумно.Что действительно важно, так это то, что вы убираете за собой, регистрируетесь и определяете разумную политику повторных попыток, прежде чем уведомлять кого-либо.

Блок обработки исключений в библиотеке предприятия может оказаться полезным, так как вы можете изменить политику исключений в конфигурации безизменение кода.

0 голосов
/ 01 июля 2010

Глотать исключения редко бывает хорошей идеей, и, как говорит Скотт в своей статье, на самом деле есть только несколько действительных случаев, когда это может быть лучшим вариантом.

Мой совет: во-первых, знать, какие исключения вы ловите, и ловить их. Это будет более полезно для вас в будущем, если вы знаете, что ловите, а не общий (Exception e)

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...