visual targeting studio net framework developer .net vb.net exception-handling windows-services

.net - studio - net framework 4.7 2 targeting pack



UnhandledException handler en.Net Windows Service (2)

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

Normalmente usarí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 hasta donde puedo decir que esto no logra nada gana un Servicio de Windows tan Terminé con este patrón en mis 2 (o 4) puntos de entrada al 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 en que mi componente de manejo de excepciones personalizado pueda lidiar con esto mejor, así que no tengo que llenar mi OnStart con una desordenada manipulación de plomería?


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 versión de mi máquina "System.ServiceProcess, Version = 2.0.0.0" descompila de esta manera:

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

Entonces, como se llama a Me.OnStart (args) desde la parte Try de un bloque Try Catch, supongo que cualquier cosa que ocurra dentro del método OnStart está efectivamente envuelto por ese bloque Try Catch y, por lo tanto, cualquier excepción que ocurra no se manipulará técnicamente como 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 se activan.