2011-04-23 19 views
65

到目前为止,我只是在Program.cs入口点的Application.Run周围放置了一个try/catch块。这在调试模式下捕获了所有异常,但是当我在没有调试模式的情况下运行程序时,异常不再被处理。我得到未处理的异常框。我该如何制作能够捕获WinForms应用程序中所有“未处理”异常的东西?

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

回答

87

的例子来看看从ThreadException documentation

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

你可能也想不在调试时捕获异常,因为这样可以更容易地进行调试。这是有点破解,但你可以包装上面的代码

if (!AppDomain.CurrentDomain.FriendlyName.EndsWith("vshost.exe")) { ... } 

为了防止在调试时捕获异常。

+1

我做了一个后台工作,并且在dowork事件处理程序中,我暗中引起了一个空引用异常。然而它并没有被AppDomain.CurrentDomain.UnhandledException捕获,尽管设置了这些:Application.ThreadException + = new System.Threading.ThreadExceptionEventHandler(Application_ThreadException); Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); AppDomain.CurrentDomain.UnhandledException + = new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); – 2011-04-23 08:25:35

+3

@IsaacB,后台工作人员本身捕获异常。您甚至可以在RunWorkerCompleted中查看异常,查看RunCompletedEventArgs.Error属性。 – 2011-04-23 08:33:46

+1

您可以通过将其添加到主窗体的OnLoad中来测试其他线程的异常处理。 new Thread(()=> {throw new Exception();})。Start(); – 2011-04-23 08:36:05

8

您可以使用NBug库。用最少的设置是这样的:

NBug.Settings.Destination1 = "Type=Mail;[email protected];[email protected];SmtpServer=smtp.mycompany.com;"; 
AppDomain.CurrentDomain.UnhandledException += NBug.Handler.UnhandledException; 
Application.ThreadException += NBug.Handler.ThreadException; 

你可以开始收集有关应用程序的所有未处理的错误,即使它部署到客户端的信息。如果你不希望使用第三方库,你要重视以下事件:

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

。如果您有进一步的问题(http://www.nbusy.com/forum/f11/)或使用[nbug]标签,请使用NBug项目论坛。 – 2011-04-23 06:11:10

+0

当然,您也可以订阅UnhandledException事件的“常规”事件处理程序。请参阅http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx – neo2862 2011-04-23 06:38:01

+0

Win7 + VS10的人,如果我订阅这些事件订阅不运行,而不是常规的Windows Vista/7对话框显示“在线检查解决方案”或“关闭程序”等。但如果我不订阅,我会得到常规的.NET未处理异常窗口。这种情况发生在Release和Debug版本上,也尝试设置Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);'不改变任何东西。 – gideon 2011-04-23 06:52:06

24

在NET 4中,某些例外是no longer caught by default;这些往往是指示可执行文件(可能是致命的)损坏状态的异常,例如AccessViolationException。

尝试在主要方法前使用[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; 
    } 
+0

我可以使用'AppDomain.CurrentDomain.UnhandledException'和'Application.ThreadException'来处理'[HandleProcessCorruptedStateExceptions]'标签吗? – Kiquenet 2017-03-01 10:03:02

6

一个很好的例子可以在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"); 
    } 
相关问题