2008-09-12 18 views
24

¿Es posible utilizar un controlador de excepción no controlada en un servicio de Windows?controlador UnhandledException en .Net Windows Service

Normalmente, utilizaría un Componente de manejo de excepciones construido a medida que registra, teléfono, etc. Este componente agrega un controlador a System.AppDomain.CurrentDomain.UnhandledException pero, por lo que puedo ver, esto no logra nada. un servicio de Windows por lo que terminan con este patrón en mis 2 (o 4) puntos de entrada de servicio:

 

    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 
 

¿hay alguna manera mi componente de control de excepciones personalizado puede hacer frente a este mejor, así que no tengo que llenar mi OnStart con una desordenada manipulación de plomería?

Respuesta

15

Ok, he investigado un poco más sobre esto ahora. Cuando crea un servicio de Windows en .Net, crea una clase que hereda de System.ServiceProcess.ServiceBase (en VB esto está oculto en el archivo .Designer.vb). A continuación, anula las funciones OnStart y OnStop, y OnPause y OnContinue si así lo desea. Estos métodos se invocan desde dentro de la clase base, así que hice un poco de hurgar con el reflector. OnStart es invocado por un método en System.ServiceProcess.ServiceBase llamado ServiceQueuedMainCallback. La vesión en mi máquina "System.ServiceProcess, versión = 2.0.0.0" descompile así:

 

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 
 

Así pues Me.OnStart (args) se llama desde dentro de la porción Trata de un bloque Try Catch Asumo que todo lo que sucede dentro del método OnStart está efectivamente envuelto por ese bloque Try Catch y, por lo tanto, cualquier excepción que ocurra no será técnicamente no controlada, ya que en realidad se manejan en ServiceQueuedMainCallback Try Catch. Así que CurrentDomain.UnhandledException nunca ocurre, al menos durante la rutina de inicio. Los otros 3 puntos de entrada (OnStop, OnPause y OnContinue) se invocan desde la clase base de forma similar.

Así que 'creo' que explica por qué mi componente Exception Handling no puede detectar UnhandledException en Start y Stop, pero no estoy seguro si explica por qué los temporizadores configurados en OnStart no pueden causar una excepción no controlada cuando fuego.

+3

He encontrado que el evento UnhandledException en un servicio recibe excepciones en otros hilos, siempre que conecte el manejador de eventos desde el principio. Lo conecté en el constructor del servicio en lugar del método OnStart(). Esto también elimina la tubería de excepción fea de su OnStart(). – saille

2

Puede suscribirse al AppDomain.UnhandledException event. Si tiene un bucle de mensaje, puede vincularlo al Application.ThreadException event.

+0

dado que mi respuesta fue eliminada (hace algunos años) pensé en volver a ponerla como un comentario, que es lo que debería haber sido todo el tiempo: gracias por la respuesta Garo pero como dije en mi pregunta original , nuestro controlador de excepción agrega un controlador a System.AppDomain.CurrentDomain.UnhandledException simplemente no funciona cuando se lo utiliza en el contexto de un servicio de Windows. – Scott

Cuestiones relacionadas