場(chǎng)景:在運行、調試代碼的時(shí)候,往往會(huì )遇到一些異常情況,很多時(shí)候我們代碼寫(xiě)得足夠健壯,所以出現的概率比較低,但是如果一旦出現,我們又沒(méi)處理好,就可能會(huì )導致程序的崩潰、退出;當然還有一部分在方法內被我們用try{} catch{}給處理掉了,但是不得不承認,還是會(huì )有極少的異常未被規避,或者說(shuō),相信不是所有的方法內都做了異常處理,所以如何處理這些異常就顯得尤為重要
需求:能否提供一個(gè)捕捉全局異常的方式,并且最好能知道異常出在哪個(gè)位置?這樣首先可以規避掉未處理的異常,增強程序的可用性,然后一旦出現問(wèn)題又能夠精準定位、方便排查。

開(kāi)發(fā)環(huán)境:.NET Framework版本:4.5
開(kāi)發(fā)工具: Visual Studio 2013
實(shí)現代碼:
/// <summary>/// 應用程序的主入口點(diǎn)。/// </summary>[STAThread]static void Main(){BindExceptionHandler();Application.EnableVisualStyles();Application.SetCompatibleTextRenderingDefault(false);Application.Run(new Form1());}/// <summary>/// 綁定程序中的異常處理/// </summary>private static void BindExceptionHandler(){//設置應用程序處理異常方式:ThreadException處理Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);//處理UI線(xiàn)程異常Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);//處理未捕獲的異常AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);}/// <summary>/// 處理UI線(xiàn)程異常/// </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, "系統錯誤", 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, "系統錯誤", MessageBoxButtons.OK, MessageBoxIcon.Error);}/// <summary>h/// 生成自定義異常消息/// </summary>/// <param name="ex">異常對象</param>/// <param name="backStr">備用異常消息:當ex為null時(shí)有效</param>/// <returns>異常字符串文本</returns>private static string GetExceptionMsg(Exception ex, string backStr){StringBuilder sb = new StringBuilder();sb.AppendLine("****************************異常文本****************************");sb.AppendLine("【出現時(shí)間】:" + DateTime.Now);if (ex != null){sb.AppendLine("【異常類(lèi)型】:" + ex.GetType().Name);sb.AppendLine("【異常信息】:" + ex.Message);sb.AppendLine("【堆棧調用】:" + 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í)現效果:

代碼解析:首先就是在Program文件中新建一個(gè)函數:BindExceptionHandler,在此方法綁定程序中的異常處理,即UI線(xiàn)程異常方法:Application_ThreadException和未捕獲的異常處理方法CurrentDomain_UnhandledException。最后再在Main函數中調用即可。然后在Form中隨便寫(xiě)個(gè)可造成異常的代碼,即效果如上圖。
另外在方法內部處理返回邏輯的時(shí)候,也可以考慮使用異常,既保證了函數的健壯性,又可以統一處理錯誤,即將所有的非正確的值以異常的方式拋出來(lái),而不是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;}}
聯(lián)系客服