Обработчик UnhandledException в службе Windows .Net

Можно ли использовать обработчик UnhandledException в службе Windows?

Обычно я бы использовал специально созданный компонент обработки исключений, который ведет журнал, звонит домой и т. д. Этот компонент добавляет обработчик к System.AppDomain.CurrentDomain.UnhandledException, но, насколько я могу судить, это ничего не дает выиграть службу Windows, поэтому Я получаю этот шаблон в моих 2 (или 4) точках входа в Сервис:


    Protected Overrides Sub OnStart(ByVal args() As String)
        ' Add code here to start your service. This method should set things
        ' in motion so your service can do its work.
        Try
            MyServiceComponent.Start()
        Catch ex As Exception
            'call into our exception handler
            MyExceptionHandlingComponent.ManuallyHandleException (ex)
            'zero is the default ExitCode for a successfull exit, so if we set it to non-zero
            ExitCode = -1
            'So, we use Environment.Exit, it seems to be the most appropriate thing to use
            'we pass an exit code here as well, just in case.
            System.Environment.Exit(-1)
        End Try
    End Sub

Есть ли способ, которым мой компонент Custom Exception Handling может справиться с этим лучше, чтобы мне не приходилось заполнять свой OnStart беспорядочной сантехникой для обработки исключений?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
25
0
13 451
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы можете подписаться на AppDomain.UnhandledException событие. Если у вас есть цикл сообщений, вы можете привязать к Application.ThreadException событие.

учитывая, что мой ответ вам был удален (несколько лет назад), я подумал, что верну его как комментарий, что и должно было быть всегда: Спасибо за ответ, Гаро, но, как я сказал в своем исходном вопросе, наше исключение обработчик добавляет обработчик к System.AppDomain.CurrentDomain.UnhandledException, он просто не работает при использовании в контексте службы Windows.

Scott 06.08.2013 06:40
Ответ принят как подходящий

Хорошо, сейчас я немного исследовал это. Когда вы создаете службу Windows в .Net, вы создаете класс, который наследуется от System.ServiceProcess.ServiceBase (в VB это скрыто в файле .Designer.vb). Затем вы переопределяете функции OnStart и OnStop, а также OnPause и OnContinue, если хотите. Эти методы вызываются из базового класса, поэтому я немного покопался с отражателем. OnStart вызывается методом в System.ServiceProcess.ServiceBase, который называется ServiceQueuedMainCallback. Версия на моей машине "System.ServiceProcess, Version = 2.0.0.0" декомпилируется следующим образом:


Private Sub ServiceQueuedMainCallback(ByVal state As Object)
    Dim args As String() = DirectCast(state, String())
    Try 
        Me.OnStart(args)
        Me.WriteEventLogEntry(Res.GetString("StartSuccessful"))
        Me.status.checkPoint = 0
        Me.status.waitHint = 0
        Me.status.currentState = 4
    Catch exception As Exception
        Me.WriteEventLogEntry(Res.GetString("StartFailed", New Object() { exception.ToString }), EventLogEntryType.Error)
        Me.status.currentState = 1
    Catch obj1 As Object
        Me.WriteEventLogEntry(Res.GetString("StartFailed", New Object() { String.Empty }), EventLogEntryType.Error)
        Me.status.currentState = 1
    End Try
    Me.startCompletedSignal.Set
End Sub

Итак, поскольку Me.OnStart (args) вызывается из части Try блока Try Catch, я предполагаю, что все, что происходит в методе OnStart, эффективно обертывается этим блоком Try Catch, и поэтому любые возникающие исключения технически не обрабатываются как они фактически обрабатываются в ServiceQueuedMainCallback Try Catch. Таким образом, CurrentDomain.UnhandledException никогда не возникает, по крайней мере, во время процедуры запуска. Остальные 3 точки входа (OnStop, OnPause и OnContinue) вызываются из базового класса аналогичным образом.

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

Я обнаружил, что событие UnhandledException в службе действительно получает исключения в других потоках, если вы очень рано подключаете обработчик событий. Я подключил его к конструктору службы, а не к методу OnStart (). Это также удаляет уродливые исключения из вашего OnStart ().

saille 24.02.2010 02:19

Другие вопросы по теме