2008-09-12 2 views
24

Возможно ли использовать обработчик UnhandledException в службе Windows?Обработчик UnhandledException в .Net службе 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 
 

есть ли способ моего пользовательский компонент Обработки исключений может справиться с этим лучше, так что я не должен заполнить мой OnStart с беспорядочной обработкой обработки исключений?

ответ

15

Хорошо, я сделал немного больше исследований в этом сейчас. Когда вы создаете службу 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 (арг) вызываются внутри Try части Try Выгоды блока я полагаю, что все, что происходит в методе OnStart, эффективно завершается блоком Try Catch, и поэтому любые возникающие исключения не являются технически необработанными, поскольку они фактически обрабатываются в ServiceQueuedMainCallback Try Catch. Таким образом, CurrentDomain.UnhandledException никогда не происходит, по крайней мере, во время запуска. Другие 3 точки входа (OnStop, OnPause и OnContinue) вызывается из базового класса аналогичным образом.

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

+3

Я обнаружил, что событие UnhandledException в службе получает исключения в других потоках, если вы подключаете обработчик событий очень рано. Я подключил его в конструкторе службы, а не в методе OnStart(). Это также удаляет уродливое исключение из вашего OnStart(). – saille 2010-02-23 23:19:46

2

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

+0

, так как мой ответ на вас был удален (несколько лет назад) Я думал, что верну его в качестве комментария, и это то, что должно было быть все время: спасибо за ответ Гаро, но, как я сказал в своем первоначальном вопросе , наш обработчик Exception добавляет обработчик к System.AppDomain.CurrentDomain.UnhandledException, он просто не работает при его использовании в контексте службы Windows. – Scott 2013-08-06 02:40:03

Смежные вопросы