如何在c#中捕获未处理的异常?

时间:2012-05-11 13:53:47

标签: c#-4.0 exception-handling error-handling c#-3.0

我正试图在我的程序中捕获任何unhandeled Exception,我在Program主类中使用此代码

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对话框。应用程序不会退出。当然在实际情况下,我会记录/邮寄错误。但我想理解为什么在我拦截我的异常后继续执行?感谢

3 个答案:

答案 0 :(得分: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();
        }
    }

答案 1 :(得分:1)

你不必使用Application.Exit或Environment.Exit,这只是visual studio的行为,它一直在拦截导致未处理的异常行,但实际上你的应用程序将崩溃(退出)如果isTerminating标志是设置的,这是正确的使用它,我建议不要使用任何用户界面这个也没有任何其他资源饥饿的进程在这个事件只是静默日志会做。

这个事件的目的是获取日志为什么它确实发生了,这不是让你的应用程序在它崩溃或道歉用户看起来很好的一点。但是当用户下次登录时你将有机会做到。

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

我通常使用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。

答案 2 :(得分:0)

Use Environment.Exit() 

而不是

Application.Exit()