如何正确捕获WinForms应用程序中的所有未处理的exception

我想为我的WinForms应用程序中的任何线程设置所有未处理exception的处理程序方法。 我自己不创建任何应用程序域。

根据UnhandledException文档,我需要通过Application.SetUnhandledExceptionMode方法设置UnhandledExceptionMode.ThrowException模式来捕获主线程的exception:

在使用Windows窗体的应用程序中,主应用程序线程中的未处理exception会导致引发Application.ThreadException事件。 如果处理此事件,则默认行为是未处理的exception不会终止应用程序,尽管应用程序处于未知状态。 在这种情况下,不会引发UnhandledException事件。 可以通过使用应用程序配置文件或使用Application.SetUnhandledExceptionMode方法在连接ThreadException事件处理程序之前将模式更改为UnhandledExceptionMode.ThrowException来更改此行为。 这仅适用于主应用程序线程。 针对在其他线程中引发的未处理exception引发UnhandledException事件

因此,生成的代码如下所示:

  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)); } 

可以吗? 它会从任何线程(包括主线程,UI线程和Task类创建的所有线程)中捕获所有未处理的exception吗? 我是否正确理解了文档?

是的,我在这里看到了这样的问题,但我不明白我为什么还要使用以下代码:

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

您应该订阅这两个事件。 请注意,即使这样也不会自动捕获其他线程中的所有内容。 例如,当异步调用委托时,只有在调用EndInvoke时,exception才会传播到调用者线程。

  [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 }