处理代码(如,回滚一个事务)然后再抛出异常。但很多人 会犯下以下的错误:
try { // 一些代码 } catch (Exception ex) { // 写日志 throw ex; }
为什么这个是错误的呢?因为,当你检查堆栈跟踪时,异常将会运行到 “throw ex”这一行,隐藏了真实的出错位置。你可以试一下。
try { //… }
catch (Exception ex) { //… throw; }
观察以上代码什么改变了呢?取代了这个将会抛出新异常同时清空堆栈追 踪的“throw ex;”语句,我们使用了简单的“throw;”语句。如果你没有指 定这个异常,throw 声明将会仅仅再次抛出 catch 声明捕获的异常。这将会保证 你的堆栈追踪完整无缺,但是依然允许你在 catch 模块中放入代码。
全局错误捕获
尽管你已经在极大部分的代码里面加入 try{}catch{}错误捕获语句, 但依然 无法肯定你的代码不会有未捕获的错误。允许未捕获错误的发生,会直接让程序 非法操作,并且无法获取该错误的详细信息。
全局错误 Application.ThreadException 的捕获能帮你解决这个
问题。 首先, 我们先建立一个用户错误处理类:
///
/// 用户错误处理类 /// public static class UserException {
///
/// 全局未捕获错误处理函数 /// public static void ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e) { Exception ex = e.Exception; //写日志 Application.Exit(); }
///
/// 全局错误处理函数 /// public static void DoException(Exception ex) { //写日志 }
}
然后在应用程序 Program 类中,添加事件委托:
//委托错误处理事
件 Application.ThreadException += new System.Threading.ThreadExceptionEventHandler( UserException.ThreadException);
事实上,错误捕获以后,应用程序应该关闭,而不应该继续运行。但是添加 全局错误捕获以后, 可以记录下未知错误的详细信息, 甚至做更多的事情, 例如: 错误发送。
应用程序域级别的错误捕获 应用程序域级别的错误捕获
事实上,Application.ThreadException 不是万能的,最重要的一点,它不 能捕获线程级的错误。 这里介绍另外一种错误捕获 AppDomain. UnhandledException 方法,它是基 于应用程序域(一种边界,它由公共语言运行库围绕同一应用程序范围内创建的 对象建立。 应用
程序域有助于将在一个应用程序中创建的对象与在其他应用程序 中创建的对象隔离,以使运行时行为可以预知。在一个单独的进程中可以存在多 个应用程序域。)级别的。 然而必须告诉你的是,这个方法并不建议用于捕获线程级的错误。理由有很 多,其中一个是,此方法捕获错误后,程序必须退出,因此无法实现某些中断线 程而主进程继续允许的需求。 同样我们需要建立一个应用程序错误处理类:
///
/// 应用程序错误处理类 /// public static class AppException { ///
/// 整个应用程序域中未捕获错误处理函数 /// public static void DomainUnhandledException(object sender, UnhandledExceptionEventArgs args) { Exception ex = (Exception)args.ExceptionObject; //应用程序必须关闭,只能提前写写日志了 Application.Exit(); Environment.Exit(0); } }
然后在应用程序 Program 类中,添加事件委托:
//委托错误处理事件 AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler( AppException.DomainUnhandledException);
必须记住的是,捕获应用程序域的错误以后,程序必须用语句关闭,否则程 序依然会发生恐怖非法操作。
最后
此文并没有介绍调试技巧,然而预防胜于补漏,合理利用.NET 的异常处理机 制,就能很好的捕获到错误及其信息,减少调试的时间。
最后想说明的是,发生错误并不可怕;可怕的是,错误重复发生,而你却对 它一无所知。