为了增强现在正在开发的系统的健壮性,需要捕获运行时出现的无法预料而且没有被处理(unhandled)的异常。查了资料后,找到了使用 Application.ThreadException 事件处理这些异常的方法,基本步骤包括,
1、为ThreadException事件添加一个处理异常的函数句柄
2、定义处理异常的函数
例子如下:
[STAThread] static void Main() { Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException); Application.Run(new FrmMain()); } private static void Application_ThreadException(object sender, ThreadExceptionEventArgs e) { MessageBox.Show("Unhandled exception: "+e.Exception.ToString()); }这种方法简单易行,而且处理效率较高,可以按照用户的意图,很方便的添加处理异常理的其他功能。但我发现,如果使用第三方提供的控件时,根本不起作用,原应可能是第三方控件运行在不同的线程中。在Microsoft的帮助中也确实提到了,上面的方法只能处理主线程中未处理的异常。好了,上网查,找到了下面的方法,使用 AppDomain.UnhandledException 替代 Application.ThreadException 。
首先需要了解的是,此时定义的事件处理函数需要在抛出异常的线程中执行,但是在主线程中给出异常提示都是在主线程中完成的,那么如何解决这个问题呢?下面的代码给出了一个比较完整的解决方案。
private delegate void ExceptionDelegate(Exception x); static private FrmMain _MainForm; /// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main() { _MainForm = new FrmMain(); AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(AppDomain_UnhandledException); Application.Run(_MainForm); } private static void AppDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) { Exception exception; exception = e.ExceptionObject as Exception; if (exception == null) { // this is an unmanaged exception, you may want to handle it differently return; } PublishOnMainThread(exception); } private static void PublishOnMainThread(Exception exception) { if (_MainForm.InvokeRequired) { // Invoke executes a delegate on the thread that owns _MainForms's underlying window handle. _MainForm.Invoke(new ExceptionDelegate(HandleException), new object[] {exception}); } else { HandleException(exception); } } private static void HandleException(Exception exception) { if (SystemInformation.UserInteractive) { using (ThreadExceptionDialog dialog = new ThreadExceptionDialog(exception)) { if (dialog.ShowDialog() == DialogResult.Cancel) return; } Application.Exit(); Environment.Exit(0); } } private void ThreadMethod() { throw new Exception("From new thread"); } private void button1_Click(object sender, System.EventArgs e) { Thread thread; thread = new Thread(new ThreadStart(ThreadMethod)); thread.Start(); }需要注意的是:
1、需要为所有的 AppDomain 的 UnhandledException 添加一个处理
2、 UnhandledExceptionEventArgs 参数中包含一个 IsTerminating 属性,表示是否中止 common language runtime