一般来说方法内我们都会有try..catch来捕获异常,但如果主程序发生一些特殊异常,是捕获不到的,需要处理Application.ThreadException异常来捕获异常,进行记录,以便跟踪处理。
.Net Winform有着自己的未处理异常机制。 Winform内部的代码会在Applicatin.Run方法里面为消息循环创建一个大的try...catch。 这样, 任何在GUI主线程里面的异常都会被这个try...catch所捕捉到, 这个默认的未处理异常handler会提取异常的所有信息然后显示在一个错误对话框里面,接着程序就中止了。这样我的try...catch就没有作用了,即下面的捕捉异常的代码是无效的。
static void Main()
{
try
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new mainfrm());
}
catch(Exception e)
{
MessgaeBox.Show(e.Message);
}
}
对于这个问题,可以处理Application.ThreadException异常,这样就可以拦截GUI主线程里面的异常了:
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);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new InLisServer_Form());
}
catch (Exception ex)
{
WriteException("入口点异常",ex);
}
}
/// <summary> 未处理UI异常
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
Exception error = e.Exception as Exception;
WriteException("未处理UI异常", error);
}
/// <summary> 未处理非UI线程异常
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Exception error = e.ExceptionObject as Exception;
WriteException("未处理非UI线程异常", error);
}
/// <summary> 记录异常
/// </summary>
/// <param name="error"></param>
static void WriteException(string Type, Exception error)
{
try
{
string str = "";
if (error != null)
{
str = string.Format(Type + "异常类型:{0}\r\n异常消息:{1}\r\n异常信息:{2}\r\n",
error.GetType().Name, error.Message, error.StackTrace + "\r\n" + error.ToString());
}
Loger.writeLog(str);
}
catch (Exception ex)
{
Loger.writeLog("记录日志时出错\r\n"+ex.ToString());
}
}
Loger.cs
/// <summary> 应用服务程序日志
/// </summary>
public class Loger
{
public static void writeLog(string strLog)
{
try
{
DateTime dtnow = System.DateTime.Now;
string path = AppDomain.CurrentDomain.BaseDirectory + @"\syslog";
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
string date = System.DateTime.Now.ToString("yyyyMMdd");
string FileName = path+"\\" + date + ".txt";
StreamWriter sw = new StreamWriter(FileName, true, Encoding.Unicode);
sw.WriteLine(dtnow.ToString() + " " + strLog);
sw.Flush();
sw.Close();
}
catch(Exception ex)
{
//System.Windows.Forms.MessageBox.Show("写日志出错\r\r" + ex.ToString());
}
}
}