毕竟人不是神,谁写的程序都会有bug,有了bug不可怕,可怕的是出错了,你却不知道错误在哪里。所以我们需要将应用程序中抛出的所有异常都记录起来,不然出了错,找问题就能要了你的命。下面我们主要讨论的是如何捕捉全局的异常。基本上在winform或web中捕获全局异常的思路都是一样的,在全局的应用程序对象中添加异常捕获的代码,并写入日志文件中。
一.在Winform程序中捕获全局异常
在winfrom中我们需要了解Application对象中的两个事件
①Application.ThreadException 事件--当UI线程中某个异常未被捕获时出现。
②AppDomain.UnhandledException 事件--当非UI线程中某个异常未被捕获时出现。
我们需要在Program.cs中设置异常的捕捉代码(如下图所示)。LogHelper类是自定义的日志帮助类,在前面的几篇文章中已经有涉及到。
需要在Program.cs中添加的代码如下所示
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Text;
using Common;
namespace testLog4N
{
static class Program
{
///
/// 应用程序的主入口点。
///
[STAThread]
static void Main()
{
BindExceptionHandler();//绑定程序中的异常处理
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
///
/// 绑定程序中的异常处理
///
private static void BindExceptionHandler()
{
//设置应用程序处理异常方式:ThreadException处理
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
//处理UI线程异常
Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
//处理未捕获的异常
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
}
///
/// 处理UI线程异常
///
///
///
static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
LogHelper.ErrorLog(null, e.Exception as Exception);
}
///
/// 处理未捕获的异常
///
///
///
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
LogHelper.ErrorLog(null, e.ExceptionObject as Exception);
}
}
}
二、在Web中捕获全局异常
我们只需要在Global.asax文件中添加异常捕获的代码即可。
完整Global.asax代码如下所示
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.SessionState;
using Common;
namespace WebApplication_testLog4Net
{
public class Global : System.Web.HttpApplication
{
void Application_Start(object sender, EventArgs e)
{
// 在应用程序启动时运行的代码
}
void Application_End(object sender, EventArgs e)
{
// 在应用程序关闭时运行的代码
}
void Application_Error(object sender, EventArgs e)
{
// 在出现未处理的错误时运行的代码
Exception objExp = HttpContext.Current.Server.GetLastError();
LogHelper.ErrorLog("
客户机IP:" + Request.UserHostAddress + "
错误地址:" + Request.Url , objExp);
}
void Session_Start(object sender, EventArgs e)
{
// 在新会话启动时运行的代码
}
void Session_End(object sender, EventArgs e)
{
// 在会话结束时运行的代码。
// 注意: 只有在 Web.config 文件中的 sessionstate 模式设置为
// InProc 时,才会引发 Session_End 事件。如果会话模式设置为 StateServer
// 或 SQLServer,则不会引发该事件。
}
}
}
三、在WPF中捕获全局异常
我们只需要在App.xaml文件中添加异常捕获的代码即可
在WPF中捕获全局异常主要涉及到以下两个事件
1、AppDomain.UnhandledException 事件--当某个异常未被捕获时出现。主要指的是非UI线程。
2、Application.DispatcherUnhandledException 事件--如果异常是由应用程序引发,但未处理,发生。主要指的是UI线程。
完整的App.xaml文件如下所示
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Windows;
using Common;
namespace WpfApplication1
{
///
/// App.xaml 的交互逻辑
///
public partial class App : Application
{
public App()
{
this.DispatcherUnhandledException += new System.Windows.Threading.DispatcherUnhandledExceptionEventHandler(App_DispatcherUnhandledException);
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
}
void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
if (e.ExceptionObject is System.Exception)
{
LogHelper.ErrorLog(null, (System.Exception)e.ExceptionObject);
}
}
public static void HandleException(Exception ex)
{
LogHelper.ErrorLog(null,ex);
}
void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
e.Handled = true;
LogHelper.ErrorLog(null, e.Exception);
}
}
}