WinForm捕获全局异常(捕获未处理的异常)

背景

我们在做WinForm程序的时候,一般都是对异常进行处理,但是,我们要防止不小心出现未知异常,导致软件崩溃。也可采集系统未知的异常信息,防止出现异常,也无法下手。于是就有了如这篇文章标题所述的一个简单的需求。.

代码实现

1、处理未捕获的异常

/// <summary>
    ///这就是我们要在发生未处理异常时处理的方法,我这是写出错详细信息到文本,如出错后弹出一个漂亮的出错提示窗体,给大家做个参考
    ///做法很多,可以是把出错详细信息记录到文本、数据库,发送出错邮件到作者信箱或出错后重新初始化等等
    ///这就是仁者见仁智者见智,大家自己做了。
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e) {

      string str = "";
      string strDateInfo = "出现应用程序未处理的异常:" + DateTime.Now.ToString() + "\r\n";
      Exception error = e.Exception as Exception;
      if (error != null) {
        str = string.Format(strDateInfo + "异常类型:{0}\r\n异常消息:{1}\r\n异常信息:{2}\r\n",
           error.GetType().Name, error.Message, error.StackTrace);
      }
      else {
        str = string.Format("应用程序线程错误:{0}", e);
      }
      Helper.GetInstance().PlanLog(str, LogType.应用程序异常.ToString());  
      //frmBug f = new frmBug(str);//友好提示界面
      //f.ShowDialog();
      MessageBox.Show("发生致命错误,请及时联系作者!", "系统错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }

2、处理UI线程异常

 static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) {
      string str = "";
      Exception error = e.ExceptionObject as Exception;
      string strDateInfo = "出现应用程序未处理的异常:" + DateTime.Now.ToString() + "\r\n";
      if (error != null) {
        str = string.Format(strDateInfo + "Application UnhandledException:{0};\n\r堆栈信息:{1}", error.Message, error.StackTrace);
      }
      else {
        str = string.Format("Application UnhandledError:{0}", e);
      }
      Helper.GetInstance().PlanLog(str, LogType.应用程序异常.ToString());  
      //frmBug f = new frmBug(str);//友好提示界面
      //f.ShowDialog();
      MessageBox.Show("发生致命错误,请停止当前操作并及时联系作者!", "系统错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }

3、处理非UI线程异常

/// <summary>
    /// 应用程序的主入口点。
    /// </summary>
    [STAThread]
    static void Main() {
      try {
        //可定义多个线程
            Thread _UserMessageThread;                   
        _UserMessageThread = new Thread(new ThreadStart(LoginManager.GetInstance().test));
        _UserMessageThread.IsBackground = true;
        _UserMessageThread.Start();

        //处理未捕获的异常  
        Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
        //处理UI线程异常  
        Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
        //处理非UI线程异常  
        AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Xw.Common.Sys.SysConfig.AppExwcutePath = Application.ExecutablePath;
        Xw.Common.Sys.SysConfig.AppStartPath = Application.StartupPath;
        Xw.Common.Sys.SysConfig.Version = "V1.0.0";
        Xw.Common.Sys.SysConfig.SoftFullName = "拍鞋网";
        Xw.Common.Sys.SysConfig.SoftName = "软件园店";
        if (!Xw.Common.Sys.SysConfig.IsOnlyRunSoft("PaiXie.Pos.Client")) {
          Xw.Common.Sys.MsgBoxWin.ShowInformation("该程序已运行!");
          return;
        }
        Application.Run(new Login());
      }
      catch (Exception ex) {
        string str = "";
        string strDateInfo = "出现应用程序未处理的异常:" + DateTime.Now.ToString() + "\r\n";
        if (ex != null) {
          str = string.Format(strDateInfo + "异常类型:{0}\r\n异常消息:{1}\r\n异常信息:{2}\r\n",
             ex.GetType().Name, ex.Message, ex.StackTrace);
        }
        else {
          str = string.Format("应用程序线程错误:{0}", ex);
        }
        Helper.GetInstance().PlanLog(str, LogType.应用程序异常.ToString());    
        //frmBug f = new frmBug(str);//友好提示界面
        //f.ShowDialog();
        MessageBox.Show("发生致命错误,请及时联系作者!", "系统错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
      }  
    }

完整代码

using PaiXie.Pos.Client.Core;
using PaiXie.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Windows.Forms;
namespace PaiXie.Pos.Client {
  static class Program {
    
    /// <summary>
    /// 应用程序的主入口点。
    /// </summary>
    [STAThread]
    static void Main() {
      try {
        //可定义多个线程
            Thread _UserMessageThread;                   
        _UserMessageThread = new Thread(new ThreadStart(LoginManager.GetInstance().test));
        _UserMessageThread.IsBackground = true;
        _UserMessageThread.Start();

        //处理未捕获的异常  
        Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
        //处理UI线程异常  
        Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
        //处理非UI线程异常  
        AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Xw.Common.Sys.SysConfig.AppExwcutePath = Application.ExecutablePath;
        Xw.Common.Sys.SysConfig.AppStartPath = Application.StartupPath;
        Xw.Common.Sys.SysConfig.Version = "V1.0.0";
        Xw.Common.Sys.SysConfig.SoftFullName = "拍鞋网";
        Xw.Common.Sys.SysConfig.SoftName = "软件园店";
        if (!Xw.Common.Sys.SysConfig.IsOnlyRunSoft("PaiXie.Pos.Client")) {
          Xw.Common.Sys.MsgBoxWin.ShowInformation("该程序已运行!");
          return;
        }
        Application.Run(new Login());
      }
      catch (Exception ex) {
        string str = "";
        string strDateInfo = "出现应用程序未处理的异常:" + DateTime.Now.ToString() + "\r\n";
        if (ex != null) {
          str = string.Format(strDateInfo + "异常类型:{0}\r\n异常消息:{1}\r\n异常信息:{2}\r\n",
             ex.GetType().Name, ex.Message, ex.StackTrace);
        }
        else {
          str = string.Format("应用程序线程错误:{0}", ex);
        }
        Helper.GetInstance().PlanLog(str, LogType.应用程序异常.ToString());    
        //frmBug f = new frmBug(str);//友好提示界面
        //f.ShowDialog();
        MessageBox.Show("发生致命错误,请及时联系作者!", "系统错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
      }  
    }
    /// <summary>
    ///这就是我们要在发生未处理异常时处理的方法,我这是写出错详细信息到文本,如出错后弹出一个漂亮的出错提示窗体,给大家做个参考
    ///做法很多,可以是把出错详细信息记录到文本、数据库,发送出错邮件到作者信箱或出错后重新初始化等等
    ///这就是仁者见仁智者见智,大家自己做了。
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e) {

      string str = "";
      string strDateInfo = "出现应用程序未处理的异常:" + DateTime.Now.ToString() + "\r\n";
      Exception error = e.Exception as Exception;
      if (error != null) {
        str = string.Format(strDateInfo + "异常类型:{0}\r\n异常消息:{1}\r\n异常信息:{2}\r\n",
           error.GetType().Name, error.Message, error.StackTrace);
      }
      else {
        str = string.Format("应用程序线程错误:{0}", e);
      }
      Helper.GetInstance().PlanLog(str, LogType.应用程序异常.ToString());  
      //frmBug f = new frmBug(str);//友好提示界面
      //f.ShowDialog();
      MessageBox.Show("发生致命错误,请及时联系作者!", "系统错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
    static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) {
      string str = "";
      Exception error = e.ExceptionObject as Exception;
      string strDateInfo = "出现应用程序未处理的异常:" + DateTime.Now.ToString() + "\r\n";
      if (error != null) {
        str = string.Format(strDateInfo + "Application UnhandledException:{0};\n\r堆栈信息:{1}", error.Message, error.StackTrace);
      }
      else {
        str = string.Format("Application UnhandledError:{0}", e);
      }
      Helper.GetInstance().PlanLog(str, LogType.应用程序异常.ToString());  
      //frmBug f = new frmBug(str);//友好提示界面
      //f.ShowDialog();
      MessageBox.Show("发生致命错误,请停止当前操作并及时联系作者!", "系统错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
  }
}

总结

针对异常,我们肯定无法事先全部预知,所以进行全局异常捕获还是很有必要的。