如何在WinForms应用程序中创建捕获所有"未处理"异常的内容?

Isa*_*ger 81 c# debugging unhandled-exception winforms

到目前为止,我只是在程序Application.RunProgram.cs入口点周围放置一个try/catch块.这会在调试模式下很好地捕获所有异常,但是当我在没有调试模式的情况下运行程序时,不再处理异常.我得到了未处理的异常框.

我不希望这种情况发生.我希望在非调试模式下运行时捕获所有异常.该程序有多个线程,最好是来自它们的所有异常都被同一个处理程序捕获; 我想记录数据库中的异常.有没有人对如何做到这一点有任何建议?

Can*_*cer 105

看一下ThreadException文档中的示例:

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);
}
Run Code Online (Sandbox Code Playgroud)

您可能还希望在调试时不捕获异常,因为这样可以更容易地进行调试.这有点像黑客,但为此你可以用上面的代码包装

 if (!AppDomain.CurrentDomain.FriendlyName.EndsWith("vshost.exe")) { ... }
Run Code Online (Sandbox Code Playgroud)

防止在调试时捕获异常.

  • 而不是FriendlyName.EndsWith hack,尝试Debugger.IsAttached更干净. (7认同)
  • @IsaacB,后台工作者自己捕获异常.您可以查看RunWorkerCompleted中的异常,查看RunCompletedEventArgs.Error属性. (4认同)

Car*_*s P 27

在NET 4中,默认情况下不再捕获某些异常; 这些往往是异常,表示可执行文件的(可能是致命的)损坏状态,例如AccessViolationException.

尝试在main方法前面使用[HandleProcessCorruptedStateExceptions]标记,例如

using System.Runtime.ExceptionServices.HandleProcessCorruptedStateExceptions

[HandleProcessCorruptedStateExceptions]
public static int Main()
{
    try
    {
        // Catch any exceptions leaking out of the program
        CallMainProgramLoop();
    }
    catch (Exception e) // We could be catching anything here
    {
        System.Console.WriteLine(e.Message);
        return 1;
    }
    return 0;
  } 
Run Code Online (Sandbox Code Playgroud)


Seb*_*Seb 17

一个很好的例子可以在http://www.csharp-examples.net/catching-unhandled-exceptions/找到. 基本上,将你的主要更改为:

static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);
        Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
        AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

        Application.Run(new Form1());
    }

    static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
    {
        MessageBox.Show(e.Exception.Message, "Unhandled Thread Exception");
    }

    static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        MessageBox.Show((e.ExceptionObject as Exception).Message, "Unhandled UI Exception");
    }
Run Code Online (Sandbox Code Playgroud)


Teo*_*gul 9

您可以使用NBug库.使用这样的最小设置:

NBug.Settings.Destination1 = "Type=Mail;From=me@mycompany.com;To=bugtracker@mycompany.com;SmtpServer=smtp.mycompany.com;";
AppDomain.CurrentDomain.UnhandledException += NBug.Handler.UnhandledException;
Application.ThreadException += NBug.Handler.ThreadException;
Run Code Online (Sandbox Code Playgroud)

您可以开始收集应用程序中所有未处理错误的信息,即使它已部署到客户端也是如此.如果您不想使用第三方库,则应附加到以下事件:

// These two should come before enabling visual styles or running the application
AppDomain.CurrentDomain.UnhandledException += ...
Application.ThreadException += ...
...
Application.Run(new Form1());
Run Code Online (Sandbox Code Playgroud)