2012-05-11 60 views
4

我想捕捉任何异常unhandeled在我的计划,我在程序主类中使用此代码如何在c#中捕捉未处理的异常?

static class Program 
{ 
/// <summary> 
/// The main entry point for the application. 
/// </summary> 
[STAThread] 
static void Main() 
{ 
Application.EnableVisualStyles(); 
Application.SetCompatibleTextRenderingDefault(false); 

AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); 

Application.Run(new Form1()); 
} 


public static void CurrentDomain_UnhandledException(Object sender, UnhandledExceptionEventArgs e) 
{ 

MessageBox.Show((e.ExceptionObject as Exception).Message, "Unhandled domain Exception"); 
Application.Exit(); 
} 

现在即时通讯我的窗体Form1,我试图创建一个简单的异常:除以零,无一个try catch块,主模块中的代码实际上拦截了异常,但我仍然有MS Visual studio对话框。应用程序不会退出。当然在实际情况下,我会记录/邮寄错误。但我想知道为什么执行后我拦截我的异常继续?感谢

+0

使用Environment.Exit()而不是Application.Exit()。 –

回答

9

接住从主UI线程所有的异常工作对我来说:的

static class Program 
    { 
     /// <summary> 
     /// The main entry point for the application. 
     /// </summary> 
     [STAThread] 
     static void Main() 
     { 
      Application.EnableVisualStyles(); 
      Application.SetCompatibleTextRenderingDefault(false); 

      // Add handler for UI thread exceptions 
      Application.ThreadException += new ThreadExceptionEventHandler(UIThreadException); 

      // Force all WinForms errors to go through handler 
      Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); 

      // This handler is for catching non-UI thread exceptions 
      AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); 

      Application.Run(new Form1()); 
     } 

     private static void CurrentDomain_UnhandledException(Object sender, UnhandledExceptionEventArgs e) 
     { 
      try 
      { 
       Exception ex = (Exception)e.ExceptionObject; 
       MessageBox.Show("Unhadled domain exception:\n\n" + ex.Message); 
      } 
      catch (Exception exc) 
      { 
       try 
       { 
        MessageBox.Show("Fatal exception happend inside UnhadledExceptionHandler: \n\n" 
         + exc.Message, "", MessageBoxButtons.OK, MessageBoxIcon.Stop); 
       } 
       finally 
       { 
        Application.Exit(); 
       } 
      } 

      // It should terminate our main thread so Application.Exit() is unnecessary here 
     } 

     private static void UIThreadException(object sender, ThreadExceptionEventArgs t) 
     { 
      try 
      { 
       MessageBox.Show("Unhandled exception catched.\n Application is going to close now."); 
      } 
      catch 
      { 
       try 
       { 
        MessageBox.Show("Fatal exception happend inside UIThreadException handler", 
         "Fatal Windows Forms Error", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Stop); 
       } 
       finally 
       { 
        Application.Exit(); 
       } 
      } 

      // Here we can decide if we want to end our application or do something else 
      Application.Exit(); 
     } 
    } 
0
Use Environment.Exit() 

代替

Application.Exit() 
1

你不必使用Application.Exit或Environment.Exit,这只是视觉工作室的行为,它持续拦截导致未处理的异常行,但实际上,如果isTerminating标志设置,您的应用程序将崩溃(退出),这是我正确使用i t,我建议不要在这个事件中使用任何用户界面,也不要使用任何其他资源饥饿的进程,只要安静的日志就行。

这个事件的目的是获取日志为什么它确切发生,这不是让你的应用程序看起来不错,而它的崩溃,或道歉的用户。但当用户下次登录时,您将有机会做到上述情况。

因此,即使您计划通过电子邮件发送异常日志,最好的方法是编写该文件,并在下次启动应用程序时通过电子邮件发送该文件。

我通常使用log4net并使用这些事件如下。

[STAThread] 
static void Main() 
{ 
    log.Info("Starting deployer application"); 

    Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException); 
    AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); 
    Application.ApplicationExit += new EventHandler(Application_ApplicationExit); 

    Application.Run(ConnectionForm.GetInstance); 
} 

static void Application_ApplicationExit(object sender, EventArgs e) 
{ 
    log.Info("Application Closed"); 
} 

static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) 
{ 
    log.Error(string.Format("*** UNHANDLED APPDOMAIN EXCEPTION ({0}) *****", e.IsTerminating ? "Terminating" : "Non-Terminating"), e.ExceptionObject as Exception); 
} 

static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e) 
{ 
    log.Error("*** UNHANDLED THREAD EXCEPTION *****", e.Exception); 
} 

如果您从未在this can be helpful之前使用过log4net。