C# WinForm捕獲全域異常
許多小公司的項目都缺少異常處理模組,我們也是。經常會出現這種情況,使用者在UI介面操作,就直接跳出堆棧調用的異常資訊對話方塊,老闆看到那叫一個火啊!你們的代碼怎麼天天出現亂碼。呵呵!這就是沒有異常捕獲處理導致的,現在許多人寫代碼都沒意識處理異常,只要實現功能就好,我的許多組員也是如此。
項目剛接手,所以打算做一個異常全域捕獲,統一處理的模式,採用具體詳細資料的對話方塊提醒與記錄檔儲存方式。以下是根據網上找的C#winform全域異常捕獲做了點修改。
static class Program
{
/// <summary>
/// 應用程式的主進入點。
/// </summary>
[STAThread]
static void Main()
{
try
{
//設定應用程式處理異常方式:ThreadException處理
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
//處理UI線程異常
Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
//處理非UI線程異常
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
#region 應用程式的主進入點
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
#endregion
}
catch (Exception ex)
{
string str = GetExceptionMsg(ex,string.Empty);
MessageBox.Show(str, "系統錯誤", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
string str = GetExceptionMsg(e.Exception, e.ToString());
MessageBox.Show(str, "系統錯誤", MessageBoxButtons.OK, MessageBoxIcon.Error);
//LogManager.WriteLog(str);
}
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
string str = GetExceptionMsg(e.ExceptionObject as Exception, e.ToString());
MessageBox.Show(str, "系統錯誤", MessageBoxButtons.OK, MessageBoxIcon.Error);
//LogManager.WriteLog(str);
}
/// <summary>
/// 產生自訂異常訊息
/// </summary>
/// <param name="ex">異常對象</param>
/// <param name="backStr">備用異常訊息:當ex為null時有效</param>
/// <returns>例外狀況字串文本</returns>
static string GetExceptionMsg(Exception ex,string backStr)
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("****************************異常文本****************************");
sb.AppendLine("【出現時間】:" + DateTime.Now.ToString());
if (ex != null)
{
sb.AppendLine("【異常類型】:" + ex.GetType().Name);
sb.AppendLine("【異常資訊】:" + ex.Message);
sb.AppendLine("【堆棧調用】:" + ex.StackTrace);
}
else
{
sb.AppendLine("【未處理異常】:" + backStr);
}
sb.AppendLine("***************************************************************");
return sb.ToString();
}
}
-----------------
配合用log4.net做日誌記錄
下面這段配置放在app.config裡,放在<configuration>下即可
------config begin-------
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
</configSections>
<log4net debug="true">
<logger name="Admin">
<!--control log level: ALL|DEBUG|INFO|WARN|ERROR|FATAL|OFF-->
<level value="DEBUG" />
<appender-ref ref="rollingFile" />
</logger>
<appender name="rollingFile" type="log4net.Appender.RollingFileAppender,log4net" >
<param name="File" type="" value="Logs\\" />
<param name="AppendToFile" value="true" />
<param name="MaxSizeRollBackups" value="10"/>
<param name="RollingStyle" value="Date" />
<param name="DatePattern" value="yyyyMMdd".log"" />
<param name="StaticLogFileName" value="false" />
<layout type="log4net.Layout.PatternLayout,log4net">
<param name="ConversionPattern" value="%d %5p: %m%n" />
</layout>
</appender>
</log4net>
--- config end---
log.cs 類檔案,放在一個公用的地方,即可
程式裡要記錄的地方直接用
ShareLibrary.Log.Debug(str);
或者
ShareLibrary.Log.Debug(ex);
---------- cs begin-----------
using System;
using System.Collections.Generic;
using System.Text;
using log4net;
namespace ShareLibrary
{
public class Log
{
private static log4net.ILog log = log4net.LogManager.GetLogger("Admin");
public static void Debug(string message)
{
if (log.IsDebugEnabled)
{
log.Debug(message);
}
}
/// <summary>
/// 記錄異常的相關資訊,log4net
/// </summary>
/// <param name="ex1"></param>
public static void Debug(System.Exception ex1)
{
if (!log.IsDebugEnabled)
{
//若不可用,重新設定
log4net.Config.XmlConfigurator.Configure();
}
log.Debug(ex1.Message.ToString() + "\r\n" + ex1.Source.ToString() + "\r\n" + ex1.TargetSite.ToString() + "\r\n" + ex1.StackTrace.ToString());
//if (log.IsDebugEnabled)
//{
// log.Debug(ex1.Message.ToString() + "\r\n" + ex1.Source.ToString() + "\r\n" + ex1.TargetSite.ToString() + "\r\n" + ex1.StackTrace.ToString());
//}
}
public static void Error(string message)
{
if (log.IsErrorEnabled)
{
log.Error(message);
}
}
public static void Fatal(string message)
{
if (log.IsFatalEnabled)
{
log.Fatal(message);
}
}
public static void Info(string message)
{
if (log.IsInfoEnabled)
{
log.Info(message);
}
}
public static void Warn(string message)
{
if (log.IsWarnEnabled)
{
log.Warn(message);
}
}
}
}
----------- cs 結束---------------