Ho realizzato alcuni UserControl in cui la parte di disegno l'ho scritta all'interno del metodo OnPaint. Oggi dopo una modifica che lanciava un'eccezione a causa di un bug ho notato questo:
Quella simpatica X rossa non la disegno io, ma il framework, facendo clic su Continue mi rimane la form con la X rossa.
La cosa che non mi piace è che si dà la possibilità all'utente di far continuare a funzionare il programma.
Per riprodurre il problema basta creare un progetto Windows Application ed aggiungere alla form principale il seguente codice:
protected override void OnPaint(PaintEventArgs e){
base.OnPaint(e); throw new Exception();}
Dopodichè eseguitelo tramite il comando Start Without Debugging.
Ho fatto un pò di ricerche su internet ed ho trovato il post WinForms Catch-All Exception Handling del blog di Craig Andera e il tip Gestione Errori Centralizzata di Corrado Cavalli.
In sintesi in un'applicazione WindowsForms si può sottoscrivere l'evento Application.ThreadException in modo da evitare la finestra standard di .NET che visualizza le eccezioni non gestite e far terminare il programma in maniera più user friendly
Nell'esempio seguente il programma visualizza una message box quando viene lanciata un eccezione non gestita e poi termina. Ovviamente è solo un esempio, nel codice di produzione si potrebbe inserire la possibilità di mandare l'errore via mail visualizzando un messaggio più user friendly.
[STAThread]static void Main() {
Application.ThreadException +=
new System.Threading.ThreadExceptionEventHandler(Application_ThreadException); Application.Run(
new Form1());}
private static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
MessageBox.Show(e.Exception.Message);
Application.Exit();
}
Attenzione che questo vale solo per il thread di UI, per le altre eccezioni non gestite si dovrebbe usare AppDomain.UnhandledException come spiegato nel post del blog delle msdn.