Come catturare tutte le eccezioni non gestite nell’applicazione WinForms correttamente

Voglio impostare il metodo gestore per tutte le eccezioni non gestite da qualsiasi thread nella mia applicazione WinForms. Non creo domini applicativi da solo.

Secondo la documentazione di UnhandledException , ho bisogno di impostare la modalità UnhandledExceptionMode.ThrowException tramite il metodo Application.SetUnhandledExceptionMode per catturare anche le eccezioni del thread principale:

Nelle applicazioni che utilizzano Windows Form, le eccezioni non gestite nel thread dell’applicazione principale causano l’aumento dell’evento Application.ThreadException. Se questo evento viene gestito, il comportamento predefinito è che l’eccezione non gestita non risolve l’applicazione, anche se l’applicazione viene lasciata in uno stato sconosciuto. In tal caso, l’evento UnhandledException non viene generato. Questo comportamento può essere modificato utilizzando il file di configurazione dell’applicazione o utilizzando il metodo Application.SetUnhandledExceptionMode per modificare la modalità su UnhandledExceptionMode.ThrowException prima che il gestore eventi ThreadException sia collegato. Questo si applica solo al thread dell’applicazione principale. L’evento UnhandledException viene generato per eccezioni non gestite generate in altri thread

Quindi, il codice risultante sarà simile al seguente:

  public static void UnhandledExceptionEventHandler(object sender, UnhandledExceptionEventArgs e) { // ... } [STAThread] static void Main(string[] args) { Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException); AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(UnhandledExceptionEventHandler); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new MainForm(pathToCheck)); } 

Va bene? Otterrà tutte le eccezioni non gestite da qualsiasi thread (incluso il thread principale, il thread dell’interfaccia utente e tutti i thread creati dalla class Task )? Ho capito correttamente la documentazione?

Sì, ho visto domande come questa qui, ma non capisco perché dovrei usare anche il seguente codice:

 Application.ThreadException += new ThreadExceptionEventHandler(ErrorHandlerForm.Form1_UIThreadException); 

Dovresti sottoscrivere entrambi gli eventi. Nota che anche questo non catturerà automaticamente tutto da altri thread. Ad esempio, quando i delegati vengono richiamati in modo asincrono, l’eccezione verrà propagata al thread del chiamante solo quando viene chiamato EndInvoke .

  [STAThread] static static void Main(string[] args) { AppDomain.CurrentDomain.UnhandledException += (sender, args) => HandleUnhandledException(args.ExceptionObject as Exception); Application.ThreadException += (sender, args) => HandleUnhandledException(args.Exception); } static void HandleUnhandledException(Exception e) { // show report sender and close the app or whatever }