首页 > 编程 > C# > 正文

C#程序异常关闭时的捕获

2020-01-24 00:16:15
字体:
来源:转载
供稿:网友

本文主要以一个简单的小例子,描述C# Winform程序异常关闭时,如何进行捕获,并记录日志。

概述

有时在界面的事件中,明明有try... catch 进行捕获异常,但是还是会有异常关闭的情况,所以在程序中如何最终的记录一些无法捕获的异常,会大大方便问题的定位分析及程序优化。

涉及知识点

以下两个异常事件,主要应用不同的场景。

  • Application.ThreadException 在发生应用程序UI主线程中未捕获线程异常时发生,触发的事件。
  • AppDomain.CurrentDomain.UnhandledException 当后台线程中某个异常未被捕获时触发。

源代码

主要程序(Program):

using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows.Forms;namespace DemoException{  static class Program  {    /// <summary>    /// 应用程序的主入口点。    /// </summary>    [STAThread]    static void Main()    {      Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);      //处理UI线程异常      Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);      //处理非线程异常      AppDomain.CurrentDomain.UnhandledException +=new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException) ;      Application.EnableVisualStyles();      Application.SetCompatibleTextRenderingDefault(false);      Application.Run(new FrmMain());      glExitApp = true;//标志应用程序可以退出    }    /// <summary>    /// 是否退出应用程序    /// </summary>    static bool glExitApp = false;    /// <summary>    /// 处理未捕获异常    /// </summary>    /// <param name="sender"></param>    /// <param name="e"></param>    private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)    {      SaveLog("-----------------------begin--------------------------");      SaveLog("CurrentDomain_UnhandledException"+DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss"));      SaveLog("IsTerminating : " + e.IsTerminating.ToString());      SaveLog(e.ExceptionObject.ToString());      SaveLog("-----------------------end----------------------------");      while (true)      {//循环处理,否则应用程序将会退出        if (glExitApp)        {//标志应用程序可以退出,否则程序退出后,进程仍然在运行          SaveLog("ExitApp");          return;        }        System.Threading.Thread.Sleep(2 * 1000);      };    }    /// <summary>    /// 处理UI主线程异常    /// </summary>    /// <param name="sender"></param>    /// <param name="e"></param>    private static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)    {      SaveLog("-----------------------begin--------------------------");      SaveLog("Application_ThreadException:" + e.Exception.Message);      SaveLog(e.Exception.StackTrace);      SaveLog("-----------------------end----------------------------");    }    public static void SaveLog(string log)    {      string filePath =AppDomain.CurrentDomain.BaseDirectory+ @"/objPerson.txt";      //采用using关键字,会自动释放      using (FileStream fs = new FileStream(filePath, FileMode.Append))      {        using (StreamWriter sw = new StreamWriter(fs, Encoding.Default))        {          sw.WriteLine(log);        }      }    }  }}

出错的程序:

using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Threading;using System.Threading.Tasks;using System.Windows.Forms;namespace DemoException{  public partial class FrmMain : Form  {    public FrmMain()    {      InitializeComponent();    }    private void FrmMain_Load(object sender, EventArgs e)    {          }    private void btnTestUI_Click(object sender, EventArgs e)    {      int a = 0;      int c = 10 / a;    }    private void btnTest2_Click(object sender, EventArgs e)    {      Thread t = new Thread(new ThreadStart(() =>      {        int a = 0;        int c = 10 / a;      }));      t.IsBackground = true;      t.Start();    }  }}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持武林网。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表