欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-11-30 20:04:56
本文主要以一个简单的小例子,描述C# Winform程序异常关闭时,如何进行捕获,并记录日志。 ......

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

概述

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

涉及知识点

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

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

源代码

主要程序(Program):

C# 程序异常关闭时的捕获
 1 using System;
 2 using System.Collections.Generic;
 3 using System.IO;
 4 using System.Linq;
 5 using System.Text;
 6 using System.Threading.Tasks;
 7 using System.Windows.Forms;
 8 
 9 namespace DemoException
10 {
11     static class Program
12     {
13         /// <summary>
14         /// 应用程序的主入口点。
15         /// </summary>
16         [STAThread]
17         static void Main()
18         {
19             Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
20             //处理UI线程异常
21             Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
22             //处理非线程异常
23             AppDomain.CurrentDomain.UnhandledException +=new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException) ;
24             Application.EnableVisualStyles();
25             Application.SetCompatibleTextRenderingDefault(false);
26             Application.Run(new FrmMain());
27             glExitApp = true;//标志应用程序可以退出
28         }
29 
30         /// <summary>
31         /// 是否退出应用程序
32         /// </summary>
33         static bool glExitApp = false;
34 
35         /// <summary>
36         /// 处理未捕获异常
37         /// </summary>
38         /// <param name="sender"></param>
39         /// <param name="e"></param>
40         private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
41         {
42 
43             SaveLog("-----------------------begin--------------------------");
44             SaveLog("CurrentDomain_UnhandledException"+DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss"));
45             SaveLog("IsTerminating : " + e.IsTerminating.ToString());
46             SaveLog(e.ExceptionObject.ToString());
47             SaveLog("-----------------------end----------------------------");
48             while (true)
49             {//循环处理,否则应用程序将会退出
50                 if (glExitApp)
51                 {//标志应用程序可以退出,否则程序退出后,进程仍然在运行
52                     SaveLog("ExitApp");
53                     return;
54                 }
55                 System.Threading.Thread.Sleep(2 * 1000);
56             };
57         }
58 
59         /// <summary>
60         /// 处理UI主线程异常
61         /// </summary>
62         /// <param name="sender"></param>
63         /// <param name="e"></param>
64         private static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
65         {
66             SaveLog("-----------------------begin--------------------------");
67             SaveLog("Application_ThreadException:" +  e.Exception.Message);
68             SaveLog(e.Exception.StackTrace);
69             SaveLog("-----------------------end----------------------------");
70         }
71 
72         public static void SaveLog(string log)
73         {
74             string filePath =AppDomain.CurrentDomain.BaseDirectory+ @"\objPerson.txt";
75             //采用using关键字,会自动释放
76             using (FileStream fs = new FileStream(filePath, FileMode.Append))
77             {
78                 using (StreamWriter sw = new StreamWriter(fs, Encoding.Default))
79                 {
80                     sw.WriteLine(log);
81                 }
82             }
83         }
84     }
85 }
View Code

出错的程序:

C# 程序异常关闭时的捕获
 1 using System;
 2 using System.Collections.Generic;
 3 using System.ComponentModel;
 4 using System.Data;
 5 using System.Drawing;
 6 using System.Linq;
 7 using System.Text;
 8 using System.Threading;
 9 using System.Threading.Tasks;
10 using System.Windows.Forms;
11 
12 namespace DemoException
13 {
14     public partial class FrmMain : Form
15     {
16 
17         public FrmMain()
18         {
19             InitializeComponent();
20         }
21 
22         private void FrmMain_Load(object sender, EventArgs e)
23         {
24            
25         }
26 
27         private void btnTestUI_Click(object sender, EventArgs e)
28         {
29             int a = 0;
30             int c = 10 / a;
31         }
32 
33         private void btnTest2_Click(object sender, EventArgs e)
34         {
35             Thread t = new Thread(new ThreadStart(() =>
36             {
37                 int a = 0;
38                 int c = 10 / a;
39             }));
40             t.IsBackground = true;
41             t.Start();
42         }
43     }
44 }
View Code