場(chǎng)景:在運(yùn)行、調(diào)試代碼的時(shí)候,往往會(huì)遇到一些異常情況,很多時(shí)候我們代碼寫得足夠健壯,所以出現(xiàn)的概率比較低,但是如果一旦出現(xiàn),我們又沒處理好,就可能會(huì)導(dǎo)致程序的崩潰、退出;當(dāng)然還有一部分在方法內(nèi)被我們用try{} catch{}
給處理掉了,但是不得不承認(rèn),還是會(huì)有極少的異常未被規(guī)避,或者說,相信不是所有的方法內(nèi)都做了異常處理,所以如何處理這些異常就顯得尤為重要
需求:能否提供一個(gè)捕捉全局異常的方式,并且最好能知道異常出在哪個(gè)位置?這樣首先可以規(guī)避掉未處理的異常,增強(qiáng)程序的可用性,然后一旦出現(xiàn)問題又能夠精準(zhǔn)定位、方便排查。
開發(fā)環(huán)境:.NET Framework版本:4.5
開發(fā)工具: Visual Studio 2013
實(shí)現(xiàn)代碼:
/// <summary>
/// 應(yīng)用程序的主入口點(diǎn)。
/// </summary>
[STAThread]
static void Main()
{
BindExceptionHandler();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
/// <summary>
/// 綁定程序中的異常處理
/// </summary>
private static void BindExceptionHandler()
{
//設(shè)置應(yīng)用程序處理異常方式:ThreadException處理
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
//處理UI線程異常
Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
//處理未捕獲的異常
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
}
/// <summary>
/// 處理UI線程異常
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
string str = GetExceptionMsg(e.Exception, e.ToString());
MessageBox.Show(str, "系統(tǒng)錯(cuò)誤", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
/// <summary>
/// 處理未捕獲的異常
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
string str = GetExceptionMsg(e.ExceptionObject as Exception, e.ToString());
MessageBox.Show(str, "系統(tǒng)錯(cuò)誤", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
/// <summary>h
/// 生成自定義異常消息
/// </summary>
/// <param name="ex">異常對(duì)象</param>
/// <param name="backStr">備用異常消息:當(dāng)ex為null時(shí)有效</param>
/// <returns>異常字符串文本</returns>
private static string GetExceptionMsg(Exception ex, string backStr)
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("****************************異常文本****************************");
sb.AppendLine("【出現(xiàn)時(shí)間】:" + DateTime.Now);
if (ex != null)
{
sb.AppendLine("【異常類型】:" + ex.GetType().Name);
sb.AppendLine("【異常信息】:" + ex.Message);
sb.AppendLine("【堆棧調(diào)用】:" + ex.StackTrace);
sb.AppendLine("【異常方法】:" + ex.TargetSite);
}
else
{
sb.AppendLine("【未處理異常】:" + backStr);
}
sb.AppendLine("***************************************************************");
return sb.ToString();
}
private void button1_Click(object sender, EventArgs e)
{
int x = int.Parse(textBox1.Text);
}
實(shí)現(xiàn)效果:
代碼解析:首先就是在Program文件中新建一個(gè)函數(shù):BindExceptionHandler
,在此方法綁定程序中的異常處理,即UI線程異常方法:Application_ThreadException
和未捕獲的異常處理方法CurrentDomain_UnhandledException
。最后再在Main函數(shù)中調(diào)用即可。然后在Form中隨便寫個(gè)可造成異常的代碼,即效果如上圖。
另外在方法內(nèi)部處理返回邏輯的時(shí)候,也可以考慮使用異常,既保證了函數(shù)的健壯性,又可以統(tǒng)一處理錯(cuò)誤,即將所有的非正確的值以異常的方式拋出來,而不是return;代碼如下:
private string GetMsg(int code)
{
try
{
if (code == 10)
{
return "Success";
}
else
{
throw new Exception("Error Code");
}
}
catch (Exception ex)
{
return "Error:" + ex.Message;
}
}
該文章在 2023/8/1 11:39:28 編輯過