Cómo llegar a toda la cadena de Excepciones en la Aplicación.ThreadException controlador de eventos?

StackOverflow https://stackoverflow.com/questions/61354

  •  09-06-2019
  •  | 
  •  

Pregunta

Yo estaba trabajando en la fijación de manejo de excepciones en una .NET 2.0 de la aplicación, y se topó con un extraño problema con Aplicación.ThreadException.

Lo que yo quiero es ser capaz de capturar todas las excepciones de eventos detrás de los elementos de la GUI (por ejemplo,button_Click, etc.).Luego quiero filtro de estas excepciones en la "fatalidad", por ejemplo,con algunos tipos de Excepciones a la aplicación debe seguir funcionando y con los demás debe salir.

En otro .NET 2.0 app me enteré de que, por defecto, solo en modo de depuración de las excepciones en realidad salir de una Aplicación.De ejecución o Aplicación.DoEvents llamada.En el modo de disparador esto no sucede, y las excepciones tienen que ser 'cazado' el uso de la Aplicación.ThreadException evento.

Ahora, sin embargo, me di cuenta de que el objeto de excepción aprobada en el ThreadExceptionEventArgs de la Aplicación.ThreadException evento siempre es la más interna de la excepción de la excepción de la cadena de.Para el registro/depuración/propósitos de diseño realmente quiero que la cadena completa de excepciones, sin embargo.No es fácil determinar qué sistema externo fallado por ejemplo, cuando usted acaba de llegar a manejar un SocketException:cuando se envuelve como por ejemplo,un NpgsqlException, a continuación, al menos sabes que es un problema de base de datos.

Así que, ¿cómo llegar a toda la cadena de excepciones de este evento? Es incluso posible o tengo que diseñar mi excepion manejo de otra manera?

Tenga en cuenta que debo hacer-una especie de - tener una solución el uso de Aplicación.SetUnhandledExceptionMode, pero esto está lejos de ser ideal, ya me gustaría tener a rodar mi propio bucle de mensajes.

EDITAR:para evitar más errores, el GetBaseException() método de NO hacer lo que yo quiero:sólo devuelve el interior de excepción, mientras que la única cosa que tengo ya es la más interna es la excepción.Quiero llegar a la parte más externa de excepción!

¿Fue útil?

Solución

Otros consejos

He intentado reproducir este comportamiento (siempre para obtener la más interna es la excepción),
pero me da la excepción espero, con todas InnerExceptions intacta.

Aquí está el código que he usado para la prueba:

   Private Shared Sub Test1()
      Try
         Test2()
      Catch ex As Exception
         Application.OnThreadException(New ApplicationException("test1", ex))
      End Try
   End Sub

   Private Shared Sub Test2()
      Try
         Test3()
      Catch ex As Exception
         Throw New ApplicationException("test2", ex)
      End Try
   End Sub

   Private Shared Sub Test3()
      Throw New ApplicationException("blabla")
   End Sub

Private Shared Sub HandleAppException(ByVal sender As Object, ByVal e As ThreadExceptionEventArgs)
...
End Sub

Sub HandleAppException controla la Aplicación.ThreadException.El Test1() llama al método primero.
Este es el resultado (e Como ThreadExceptionEventArgs) me meto en HandleAppException:

ThreadException http://mediasensation.be/dump/?download=ThreadException.jpg

Si usted acaba de coger y (re)producir excepciones, no InnerExceptions wil muestran, pero se anexará a la Excepción.StackTrace, como este:

en TAN.Test3() en la Prueba.vb:la línea 166
en TAN.Test2() en la Prueba.vb:línea 159
en TAN.Prueba1() en la Prueba.vb:línea 151

Normalmente, sólo se pierde toda la cadena de excepciones a excepción de la base de excepción en una Aplicación.ThreadException controlador de excepción si la excepción ocurrió en un hilo de otro.

A partir de la Biblioteca de MSDN:

Este evento permite a Windows Forms aplicación para manejar de otra manera las excepciones no controladas que se producen en Los Formularios Windows Forms los hilos.Adjunte su los controladores de eventos para el ThreadException evento para lidiar con estas excepciones, que dejará su aplicación en un estado desconocido.Donde sea posible, las excepciones deben ser manejados por un el control de excepciones estructurado bloque.

Solución:Si usted hace el roscado, asegúrese de que todos los hilos/async las llamadas están en un bloque try/catch.O como dijo usted, usted puede jugar con la Aplicación.SetUnhandledExceptionMode.

Acabo de descubrir algo interesante.Diferentes eventos GUI obtendrá resultados diferentes.Una excepción desde un Formulario.Muestra de controlador de eventos resultará en la Aplicación.ThreadException captura el interior de la mayoría de excepción, pero exactamente el mismo código que se ejecute en el Formulario.Carga evento tendrá como resultado la exterior de la mayoría de los excepción de quedar atrapado en la Aplicación.ThreadException.

¿Has probado la Excepción.GetBaseException Método?Esto devuelve la excepción que crea la Aplicación.TreadException.Entonces, usted puede utilizar el mismo proceso para subir la cadena para obtener todas las excepciones.

excepción.Método getbaseexception

Basado en parte de la información en esta cadena, he utilizado UnhandledExceptionMode.ThrowException frente a UnhandledExceptionMode.CatchException.Entonces me capturar la excepción fuera de la forma de Ejecución de() y esto me da toda la cadena de excepciones.

De acuerdo a la documentación de MSDN:

Cuando se reemplaza en una clase derivada, devuelve la Excepción que es la raíz de la causa de uno o más excepciones posteriores.

    Public Overridable Function GetBaseException() As Exception
        Dim innerException As Exception = Me.InnerException
        Dim exception2 As Exception = Me
        Do While (Not innerException Is Nothing)
            exception2 = innerException
            innerException = innerException.InnerException
        Loop
        Return exception2
    End Function

Usted podría utilizar una variación de este para analizar la excepción de la cadena.

Public Sub LogExceptionChain(ByVal CurrentException As Exception)

    Dim innerException As Exception = CurrentException.InnerException
    Dim exception2 As Exception = CurrentException

    Debug.Print(exception2.Message) 'Log the Exception

    Do While (Not innerException Is Nothing)

        exception2 = innerException
        Debug.Print(exception2.Message) 'Log the Exception

        'Move to the next exception
        innerException = innerException.InnerException
    Loop

End Sub

Este sería, me parecen exactamente lo que usted está buscando.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top