前言
上篇文章我提供了一种方案可以供我们捕获单线程程序中的所有未处理异常。但是如果程序是多线程,那么新增线程出现了异常上个方案就无能为力了。本着方案总比问题多的态度,我再给大家提供一种新的方案,供大家参考。
处理多线程程序的全局异常demo
好了下面直接上代码:
using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; using System.Threading; namespace WindowsFormsApplication2 { static class Program { /// <summary> /// 应用程序的主入口点。 /// </summary> [STAThread] static void Main() { ThreadExceptionHandler handler = new ThreadExceptionHandler(); // 设置没有没捕获的异常在这里强制被捕获 Application.SetUnhandledExceptionMode(UnhandledExceptionMode.Automatic); // 注册UI线程异常事件 Application.ThreadException += handler.Form1_UIThreadException; // 注册非UI线程异常事件 AppDomain.CurrentDomain.UnhandledException += handler.CurrentDomain_UnhandledException; Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); } } internal class ThreadExceptionHandler { /// <summary> /// 捕获UI线程的异常 /// </summary> /// <param name="sender"></param> /// <param name="t"></param> public void Form1_UIThreadException(object sender, ThreadExceptionEventArgs t) { DialogResult result = DialogResult.Cancel; try { result = ShowThreadExceptionDialog("Windows Forms UI错误", t.Exception); } catch { try { MessageBox.Show("严重的错误","Windows Forms UI错误", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Stop); } finally { Application.Exit(); } } // 点中止时退出程序 if (result == DialogResult.Abort) Application.Exit(); } /// <summary> /// 捕获非UI线程的异常, /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) { DialogResult result = DialogResult.Cancel; try { Exception ex = (Exception)e.ExceptionObject; result = ShowThreadExceptionDialog("非UI线程错误", ex); } catch (Exception exc) { try { MessageBox.Show("严重的非UI线程错误:" + exc.Message, "非UI线程错误", MessageBoxButtons.OK, MessageBoxIcon.Stop); } finally { Application.Exit(); } } // 点中止时退出程序 if (result == DialogResult.Abort) Application.Exit(); } /// <summary> /// 创建错误信息并显示 /// </summary> /// <param name="title"></param> /// <param name="e"></param> /// <returns></returns> private DialogResult ShowThreadExceptionDialog(string title, Exception e) { string errorMsg = "应用程序错误,请联系管理员," + "错误信息:\n\n"; errorMsg = errorMsg + e.Message + "\n\nStack Trace:\n" + e.StackTrace; // 在这边记下日志,一般情况下我们可以自定义日志 TODO return MessageBox.Show(errorMsg, title, MessageBoxButtons.AbortRetryIgnore,MessageBoxIcon.Stop); } } }
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Reflection; using System.Threading; namespace WindowsFormsApplication2 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, System.EventArgs e) { throw new IndexOutOfRangeException("无效的异常操作"); } private void button2_Click(object sender, System.EventArgs e) { Thread th = new Thread(new ThreadStart(ThreadStart1)); th.Start(); } private void ThreadStart1() { throw new FormatException("多线程异常,格式异常"); } } }