看了网上的一篇关于处理未处理异常的文章(原文地址http://msdn.microsoft.com/zh-cn/magazine/cc793966.aspx),里面介绍了如何在程序产生未处理异常,在程序崩溃前对异常进行最后的记录,以便查找程序崩溃原因。我按里面的做法,新建了一个WinForm的项目
在Program.cs文件的入口函数Main中添加如下代码
static void Main()
        {
            AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(UnhandledExceptionHandler);
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }        static void UnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs e)
        {
            Exception ex = (Exception)e.ExceptionObject;
            FileStream fs = new FileStream("log.txt", FileMode.OpenOrCreate, FileAccess.Write);
            BinaryWriter br = new BinaryWriter(fs);
            string msg = ex.Message;
            br.Write(msg + "\n");
            br.Flush();
            fs.Close();
            br.Close();
        }然后我点击一个button,throw出一个异常。
程序调试运行的时候可以处理到这个未处理的异常,在debug目录下看到了生成的log.txt文件,打开文件能看到写入的msg
但是在 不调试 运行的情况下,程序会弹出错误提示框,并且查看debug目录下没有生日log.txt文件换成Release模式运行也是一样的情况。可能有的朋友会说在所有可能发生异常的地方加try-catch块,但是这对于大型的程序来说几乎是不可能的。请问各位这是什么原因,如何正确处理未处理的异常?

解决方案 »

  1.   

    我不知道我的做法好不好。我是在main函数加try的
    static void Main()
    {
    try
    {
    AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(UnhandledExceptionHandler);
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new Form1());
    }
    catch(Exception ex)
    {
    FileStream fs = new FileStream("log.txt", FileMode.OpenOrCreate, FileAccess.Write);
    BinaryWriter br = new BinaryWriter(fs);
    string msg = ex.Message;
    br.Write(msg + "\n");
    br.Flush();
    fs.Close();
    br.Close();
    }
    }
      

  2.   

    Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException);Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException);
    AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(UnhandledExceptionHandler);
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new Form1());模式设为ThrowException,你才可以自己做处理,但是Crash是无法避免的...
      

  3.   


    见http://msdn.microsoft.com/zh-cn/library/system.appdomain.unhandledexception.aspx
    ...在使用 Windows 窗体的应用程序中,主应用程序线程中的未经处理的异常会导致引发 Application.ThreadException 事件。如果处理此事件,则默认行为是未经处理的异常不终止该应用程序。在这种情况下,不会引发 UnhandledException 事件。...
      

  4.   

    static void StartApp()
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
                FrmLogin frmLogin = new FrmLogin();
                if (frmLogin.ShowDialog() == DialogResult.OK)
                {                
                    FrmMain frmMain = new FrmMain();
                    Application.Run(new FrmMain());                
                }           
            }
      

  5.   


      // Summary:
            //     Never route exceptions to the System.Windows.Forms.Application.ThreadException
            //     handler. Ignore the application configuration file.
            ThrowException = 1,如果设置为ThrowException,Application.ThreadException事件是不会被触发的.
      

  6.   

    看了大家的回复,大概知道从哪里入手来解决了
    我在网上也找到了一个资料(地址http://blog.csdn.net/luminji/archive/2010/01/17/5197996.aspx),也是注册Application.ThreadException和AppDomain.Current.UnhandledException这两个事件,里面的注释说
    Application.ThreadException是捕获UI线程的未处理异常,这个会导致程序CrashAppDomain.Current.UnhandledException是捕获非UI线程的未处理异常,而这个不会导致程序Crash
    我自己测试过确实也如此。
    资料里面的Application.SetUnhandledExceptionMode是设置成CatchException的,请问这个不同的设置对处理未处理异常又有什么影响呢
      

  7.   

     // Summary:
            //     Always route exceptions to the System.Windows.Forms.Application.ThreadException
            //     handler. Ignore the application configuration file.
            CatchException = 2,也就是ThreadException肯定能抓到发生的UI线程异常.