Qual è la differenza tra Application.ThreadException e AppDomain.CurrentDomain.UnhandledException?


107

Va bene, questo è facile:

  • Qual è la differenza tra Application.ThreadExceptione
    AppDomain.CurrentDomain.UnhandledException?

  • Devo gestire entrambi?

Grazie!

Risposte:


98

Application.ThreadException è specifica di Windows Form. Winforms esegue gestori di eventi in risposta ai messaggi inviati da Windows. L'evento Click, ad esempio, sono sicuro che li conosci. Se un tale gestore di eventi genera un'eccezione, allora c'è un back-stop all'interno del ciclo di messaggi Winforms che cattura quell'eccezione.

Quel backstop attiva l' evento Application.ThreadException . Se non lo sovrascrivi, l'utente riceverà un ThreadExceptionDialog . Ciò gli consente di ignorare l'eccezione e continuare a eseguire il programma. Non è una grande idea btw.

È possibile disabilitare questo comportamento chiamando Application.SetUnhandledExceptionMode () nel metodo Main () in Program.cs. Senza quel backstop in atto, la solita cosa accade quando un thread muore a causa di un'eccezione non gestita: AppDomain.UnhandledException si attiva e il programma termina.

Fwiw: "ThreadException" è stata una scelta di nome molto scarsa. Non ha niente a che fare con i thread.


E come fermare l'applicazione WinForms dall'arresto anomalo al verificarsi di Application.ThreadException. Ho sollevato una domanda per questo [qui ] con il mio piccolo codice C #.
Mahesha999

2
Lo leggo sempre come eccezione del thread dell'applicazione, dato che winforms è associato a un singolo thread.
Gusdor

36

Dalla fonte :

Nelle applicazioni che utilizzano Windows Form, le eccezioni non gestite nel thread dell'applicazione principale causano la generazione Application.ThreadException dell'evento. Se questo evento viene gestito, il comportamento predefinito è che l'eccezione non gestita non termina l'applicazione, sebbene l'applicazione venga lasciata in uno stato sconosciuto. In tal caso, l' UnhandledException evento non viene generato. Questo comportamento può essere modificato utilizzando il file di configurazione dell'applicazione o utilizzando il Application.SetUnhandledExceptionModemetodo per modificare la modalità UnhandledExceptionMode.ThrowExceptionprima che il ThreadException gestore di eventi venga collegato. Questo vale solo per il thread dell'applicazione principale. L' UnhandledException evento viene generato per le eccezioni non gestite generate in altri thread.

A partire con Visual Studio 2005 , il Visual Basic application framework fornisce un altro evento per eccezioni non gestite nel thread dell'applicazione principale - WindowsFormsApplicationBase.UnhandledException. Questo evento ha un oggetto argomenti dell'evento con lo stesso nome dell'oggetto argomenti dell'evento utilizzato da AppDomain.UnhandledException, ma con proprietà differenti. In particolare, questo oggetto degli argomenti dell'evento ha una ExitApplicationproprietà che consente all'applicazione di continuare l'esecuzione, ignorando l'eccezione non gestita (e lasciando l'applicazione in uno stato sconosciuto). In tal caso, l'evento AppDomain.UnhandledException non viene generato.

Application.ThreadExceptionpuò essere catturato e l' applicazione potrebbe continuare (in generale non è una grande idea, ma per l'applicazione come eseguire periodicamente alcune azioni questa è una buona soluzione).

Per rilevare le eccezioni che si verificano nei thread non creati e di proprietà di Windows Form, utilizzare il AppDomain.UnhandledException. Consente all'applicazione di registrare le informazioni sull'eccezione prima che il gestore predefinito del sistema segnali l'eccezione all'utente e termini l'applicazione.
La gestione di questa eccezione non impedisce la chiusura dell'applicazione.
Il massimo che si può fare (i dati del programma possono essere danneggiati quando le eccezioni non vengono gestite) è salvare i dati del programma per il recupero successivo. Dopo di che il dominio dell'applicazione viene scaricato e l'applicazione termina.

A partire da .NET 4 , questo evento non viene generato per eccezioni che danneggiano lo stato del processo, come overflow dello stack o violazioni di accesso, a meno che il gestore di eventi non sia critico per la sicurezza e abbia l' HandleProcessCorruptedStateExceptionsAttribute attributo.

Per ulteriori dettagli, vedere MSDN .


18

OK - L'avevo davanti a me, questo bit di codice da msdn è abbastanza autoesplicativo:

public static void Main(string[] args)
{
    // Add the event handler for handling UI thread exceptions to the event.
    Application.ThreadException += new 
        ThreadExceptionEventHandler(ErrorHandlerForm.Form1_UIThreadException);

    // Set the unhandled exception mode to force all Windows Forms 
    // errors to go through our handler.
    Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);

    // Add the event handler for handling non-UI thread exceptions to the event. 
    AppDomain.CurrentDomain.UnhandledException +=
        new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

    // Runs the application.
    Application.Run(new ErrorHandlerForm());
}

3
questo è in contrasto con l'altra risposta di serhio quando dice: UnhandledExceptionMode.ThrowException dovrebbe essere impostato prima che il gestore dell'evento ThreadException sia collegato. Non sono sicuro che l'ordine sia davvero importante ...
Davide Piras

@DavidePiras sì, e c'è qualcosa di più oscuro. SetUnhandledException sembra non fare differenza nel mio caso.
nawfal

0

Il fatto è che, a ThreadExceptioncausa di un problema con il thread, Unhandled Exceptionviene attivato se il codice genera un'eccezione che non viene gestita.

Il modo più semplice per causare il secondo è creare un'app senza provare ... cattura i blocchi e lancia un'eccezione.

Ora, se hai bisogno di un'assicurazione, puoi gestirli entrambi, tuttavia se acquisisci e gestisci exceptionscorrettamente, non dovresti aver bisogno del UnhandledExceptiongestore perché è un po 'come prendere tutto.


grazie - quello su cui non ero molto chiaro è che se gestendo UnhandledException avrei catturato anche ThreadException - che sembra non essere il caso
JohnIdol
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.