18

Ho un'applicazione WPF che gira diversi thread. Ho definito un gestore di eventi DispatcherUnhandledException in App.xaml.cs che visualizza un messaggio di errore dettagliato e questo gestore viene chiamato ogni volta che il thread dell'interfaccia utente rileva un'eccezione. Il problema riguarda i thread secondari: le loro eccezioni non gestite non vengono mai gestite. Come faccio a fare questo?Catching Eccezioni non gestite nei thread secondari in WPF

codice di esempio:

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 
    //... 
} 

Edit: Una volta che si verifica un'eccezione non gestita, voglio visualizzare un messaggio di errore con una traccia dello stack, e poi uscire dall'applicazione.

risposta

17

Prova ad agganciare fino all'evento AppDomain.CurrentDomain.UnhandledException.

+1

Vedere http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx per capire perché questo deve essere utilizzato solo per registrare l'errore prima di uscire. –

+0

@Henk, questo è lo stesso link che ho già postato. Hai ragione, tuttavia, l'eccezione dovrebbe essere utilizzata solo per scopi di registrazione. – Brandon

+0

Brandon, OK, non ho controllato il tuo link (-: Ma ne consegue che ogni Thread dovrebbe gestire le proprie eccezioni. –

3

Questo è di progettazione, è necessario utilizzare un try/catch al livello più alto di DoWork. Alcuni modelli di threading si occupano di questo, date un'occhiata al Backgroundworker per un esempio.

La classe di attività .NET 4 fornisce un'interfaccia piacevole a questo problema. Fino ad allora, dovrai prenderti cura di te stesso o utilizzare i modelli BGW o IAsyncResult.

+0

Questa è una risposta molto valida, ma per la mia situazione particolare, ho in esecuzione un processo lungo e complesso in doWork(). Da quello che ho capito, i blocchi try/catch impongono una penalizzazione delle prestazioni abbastanza decente e preferisco usarli solo su piccoli blocchi di codice. – Phil

+3

No, try/catch influenza solo le prestazioni _quando_ viene generata un'eccezione e la velocità di solito non è il tuo problema più grande, nel caso normale non c'è alcun svantaggio e dopo un'eccezione 'escape' da un thread, la stabilità dell'intera app è in questione –

+0

Ok, questo ha un senso. per me. – Phil