Supponiamo di avere una semplice applicazione Windows Form il cui unico (e stupido) compito è quello di eseguire una divisione, qualcosa  del tipo

Se non eseguiamo nessuna validazione sui campi, potrebbe accadere che vengano eseguiti calcoli sbagliati (ad esempio una divisione per zero)  e di conseguenza che vengano sollevate le corrispondenti eccezioni. Per catturarle, possiamo utilizzare dei blocchi Try...Catch...Finally oppure  gestire l'evento Application.ThreadException. Così facendo, oltre alla possibilità di memorizzare un log delle eccezioni a livello di applicazione o eseguire del codice di pulizia, possiamo visualizzare una Windows Form User-Friendly, senza interrompere bruscamente l'applicazione. Per registrare il gestore  dell'evento ThreadException, possiamo aggiungere un modulo al nostro progetto e scrivere il seguente codice:
 1 <STAThread()> _
 2     Public Sub Main()
 3 
 4         'Imposta il gestore evento Application.ThreadExeception personalizzato
 5         AddHandler Application.ThreadException, AddressOf CustomErrorHandler
 6 
 7         AddHandler AppDomain.CurrentDomain.UnhandledException, AddressOf AppDomainCustomErrorHandler
 8 
 9         'Imposta il gestore evento Application.ApplicationExit personalizzato
10         AddHandler Application.ApplicationExit, AddressOf CustomApplicationExit
11 
12         Application.Run(New Form1())
13     End Sub
 
Dove il gestore CustomErrorHandler è del tipo:
 
 1  Public Sub CustomErrorHandler(ByVal sender As Object, ByVal e As System.Threading.ThreadExceptionEventArgs)
 2 
 3         Try
 4             'Gestisce l'eccezione visualizzando una finestra di dialogo comune per l'eventuali eccezioni
 5             My.Forms.frmExeception.DescrizioneEccezione = e.Exception.Message
 6             My.Forms.frmExeception.ShowDialog()
 7         Catch ex As Exception
 8 
 9         End Try
10 
11     End Sub
 
 
Il quale, in caso di eccezione, visualizza la seguente finestra di dialogo:
 
Nel Sub Main, oltre a registrare l'evento Application.ThreadException, viene registrato anche il gestore per l'evento AppDomain.CurrentDomain.UnhandledExecption, perchè nel in cui caso la nostra applicazione sfrutti il multithreading, l'eventuali eccezioni dovute ai thread secondari non sarebbero catturate da CustomErrorHandler. Il codice del gestore per l'evento AppDomain.CurrrentDomain.UnhandledException è il seguente:
 1 Public Sub AppDomainCustomErrorHandler(ByVal sender As Object, ByVal e As UnhandledExceptionEventArgs)
 2         Try
 3             'Gestisce l'eccezione visualizzando una finestra di dialogo comune per l'eventuali eccezioni
 4             'Ottiene l'oggetto Exception
 5             Dim appDomainException As Exception = DirectCast(e.ExceptionObject, System.Exception)            
 6             My.Forms.frmExeception.DescrizioneEccezione = appDomainException.Message
 7             My.Forms.frmExeception.ShowDialog()
 8 
 9             If (e.IsTerminating) Then
10                 'Operazioni di pulizia...
11             End If
12         Catch ex As Exception
13 
14         End Try
15     End Sub
 
Il quale esegue una cast dell'oggetto e.ExceptionObject in System.Exception e visualizza la finestra di dialogo su mostrata. L'istanza di oggetto UnhandledExecptionEventArgs espone la proprietà IsTerminating che indica se il common language runtime stà terminando o meno. Nel caso di UnhandledExecption, il .Net Framework , con o senza gestione del relativo evento, visualizza la classica finestra di dialogo per l'esecuzione del debug  dell'applicazione. Per testare il codice ed il relativo comportamento dell'applicazione, da Visual Studio è necessario lanciare l'applicazione  senza Debug.
Thread Exception.zip