看了网上的一篇关于处理未处理异常的文章(原文地址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块,但是这对于大型的程序来说几乎是不可能的。请问各位这是什么原因,如何正确处理未处理的异常?
在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块,但是这对于大型的程序来说几乎是不可能的。请问各位这是什么原因,如何正确处理未处理的异常?
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();
}
}
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(UnhandledExceptionHandler);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());模式设为ThrowException,你才可以自己做处理,但是Crash是无法避免的...
见http://msdn.microsoft.com/zh-cn/library/system.appdomain.unhandledexception.aspx
...在使用 Windows 窗体的应用程序中,主应用程序线程中的未经处理的异常会导致引发 Application.ThreadException 事件。如果处理此事件,则默认行为是未经处理的异常不终止该应用程序。在这种情况下,不会引发 UnhandledException 事件。...
{
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());
}
}
// Summary:
// Never route exceptions to the System.Windows.Forms.Application.ThreadException
// handler. Ignore the application configuration file.
ThrowException = 1,如果设置为ThrowException,Application.ThreadException事件是不会被触发的.
我在网上也找到了一个资料(地址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的,请问这个不同的设置对处理未处理异常又有什么影响呢
// Always route exceptions to the System.Windows.Forms.Application.ThreadException
// handler. Ignore the application configuration file.
CatchException = 2,也就是ThreadException肯定能抓到发生的UI线程异常.