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

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

概述

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

涉及知识点

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

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

主要源代码

主要程序(Program):

 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

出错的程序:

 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

 下载链接

posted @ 2018-07-29 23:19  老码识途呀  阅读(5493)  评论(5编辑  收藏  举报