18

Tengo una aplicación WPF que genera varios subprocesos. Definí un controlador de eventos DispatcherUnhandledException en App.xaml.cs que muestra un mensaje de error detallado, y se llama a este controlador cada vez que el subproceso de la interfaz de usuario encuentra una excepción. El problema es con los hilos hijos: sus excepciones no manejadas nunca se manejan. ¿Cómo hago esto?Captura de excepciones no controladas en subprocesos secundarios en WPF

Código de ejemplo:

private void Application_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e) 
{ 
    MessageBox.Show("detailed error message"); 
} 

private void Application_Startup(object sender, StartupEventArgs e) 
{ 
    //... 
    //If an Exception is thrown here, it is handled 
    //... 

    Thread[] threads = new Thread[numThreads]; 
    for(int i = 0; i < numThreads; i++) 
    { 
     threads[i] = new Thread(doWork); 
     threads[i].Start(); 
    } 
} 

private void doWork() 
{ 
    //... 
    //Exception thrown here and is NOT handled 
    //... 
} 

Editar: Una vez que ocurre una excepción no controlada, quiero mostrar un mensaje de error con un seguimiento de la pila, y luego salir de la aplicación.

Respuesta

17

Pruebe conectarse al evento AppDomain.CurrentDomain.UnhandledException también.

+1

Consulte http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx para leer por qué esto solo debe usarse para registrar el error antes de salir. –

+0

@Henk, ese es el mismo enlace que ya he publicado. Sin embargo, tiene razón, la excepción solo debe usarse con fines de registro. – Brandon

+0

Brandon, OK, no revisé su enlace (-: pero se deduce que cada subproceso debe manejar sus propias excepciones. –

3

Esto es por diseño, debe utilizar un try/catch en el nivel superior de DoWork. Algunos modelos de subprocesos sirven para esto, eche un vistazo al Backgroundworker para ver un ejemplo.

La clase Task de .NET 4 proporciona una buena interfaz para este problema. Hasta entonces, tendrá que encargarse usted mismo, o usar los modelos BGW o IAsyncResult.

+0

Esa es una respuesta muy válida, pero para mi situación particular, estoy ejecutando un proceso largo y complejo en doWork(). Por lo que entiendo, try/catch blocks impone una penalización de rendimiento bastante decente, y prefiero usarlos solo en trozos pequeños de código. – Phil

+3

No, try/catch solo afecta el rendimiento _cuando se lanza una excepción, y entonces la velocidad generalmente no es su mayor problema. En el caso normal, no hay ningún inconveniente. Y después de una excepción 'escapa' de un hilo, la estabilidad de toda su aplicación está en cuestión. –

+0

Ok, eso tiene sentido. Gracias por aclarar eso para mí. – Phil

Cuestiones relacionadas