<section name="exceptionHandling" type="Microsoft.Practices. EnterpriseLibrary. ExceptionHandling. Configuration. ExceptionHandlingSettings, Microsoft.Practices. EnterpriseLibrary. ExceptionHandling" /> |
<section name="loggingConfiguration" type="Microsoft.Practices. EnterpriseLibrary.Logging. Configuration.LoggingSettings, Microsoft.Practices. EnterpriseLibrary.Logging" /> |
<exceptionHandling> <exceptionPolicies> <add name="Global Policy"> <exceptionTypes> <add name="Exception" type="System.Exception, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" postHandlingAction="None"> <exceptionHandlers> <add name="Application Message Handler" type="ExceptionMgmtBlockExample. AppMessageExceptionHandler, ExceptionMgmtBlockExample"/> </exceptionHandlers> </add> </exceptionTypes> </add> </exceptionPolicies> </exceptionHandling> |
图1 |
使用ExceptionPolicy类
只要使用异常处理块,就必须要与ExceptionPolicy类打交道,由其引出的名为HandleException()的静态方法允许客户端程序与异常处理块相交互,在此可把策略作为参数提供。HandleException()方法使用一个类工厂来为相应的策略创建ExceptionPolicyImpl类型的对象,而ExceptionPolicyImpl对象拥有一个ExceptionPolicyEntry对象集--即在相应策略的配置文件中,每一种异常类型都对应于一个对象。对每一种异常类型,ExceptionPolicyEntry对象都包含了一个对象集,并由其实现了IExceptionHandler接口,当执行策略时,对象集就可提供异常处理块使用的序列;且每一个实现IExceptionHandler接口的对象都与对应于每种处理方法的类型相关联。
异常处理方法是 .NET类,其包装了异常处理逻辑,并实现了定义在异常处理块中的IExceptionHandler接口,默认状态下,异常处理块包含以下三种异常处理方法:
·包装处理方法:此异常处理方法用一个异常包装了另一个异常。
·取代处理方法:此异常处理方法用一个异常取代了另一个异常。
·日志记录处理方法:此异常处理方法对异常信息进行格式化处理,如通知和堆栈跟踪。日志记录处理方法将把这些信息登记入日志块,以作日后查证。
如果需要实现你自己的处理方法,通过使用企业库配置工具,也可自行扩展异常处理块。由此带来的最大好处是,你不必仅仅为了扩展它,而修改和重新构建整个程序。
使用ExceptionPolicy来处理异常
为演示异常处理块的使用,下面有一个简单的例子,例如一个名为ExceptionMgmtBlockExample 简单的Windows Form程序。在Visual Studio中创建此工程,添加前面所提到的引用,在窗体设计器中打开默认窗体,加入一个名为btnHandleException的命令按钮,修改它的单击事件如下:
private void btnHandleException_Click (object sender, EventArgs e) { try { throw new Exception("This is a test exception"); } catch (Exception ex) { bool rethrow = ExceptionPolicy.HandleException (ex, "Global Policy"); if (rethrow) { throw; } } } |
using System; using System.Collections.Specialized; using System.Windows.Forms; using Microsoft.Practices.EnterpriseLibrary.Common.Configuration; using Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder; using Microsoft.Practices.EnterpriseLibrary.ExceptionHandling; using Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Configuration; namespace ExceptionMgmtBlockExample { [ConfigurationElementType (typeof(CustomHandlerData))] public class AppMessageExceptionHandler : IExceptionHandler { public AppMessageExceptionHandler(NameValueCollection ignore) {} public Exception HandleException (Exception exception, Guid correlationID) { DialogResult result = this.ShowThreadExceptionDialog (exception); if (result == DialogResult.Abort) Application.Exit(); return exception; } private DialogResult ShowThreadExceptionDialog(Exception e) { string errorMsg = e.Message + Environment.NewLine + Environment.NewLine; return MessageBox.Show(errorMsg, "Application Error", MessageBoxButtons.OK, MessageBoxIcon.Stop); } } } |
图2 |
private void btnLogException_Click(object sender, EventArgs e) { try { throw new Exception ("This is a test exception"); } catch (Exception ex) { bool rethrow = ExceptionPolicy.HandleException (ex, "Log Only Policy"); if (rethrow) { throw; } } } |
<add name="Log Only Policy"> <exceptionTypes> <add name="Exception" type="System.Exception, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" postHandlingAction="None"> <exceptionHandlers> <add logCategory="Default Category" eventId="100" severity="Error" title="Exception Management Application Exception" priority="0" formatterType="Microsoft. Practices.EnterpriseLibrary. ExceptionHandling.TextExceptionFormatter, Microsoft.Practices.EnterpriseLibrary. ExceptionHandling" name="Logging Handler" type="Microsoft.Practices.EnterpriseLibrary. ExceptionHandling.Logging. LoggingExceptionHandler, Microsoft.Practices.EnterpriseLibrary. ExceptionHandling.Logging"/> </exceptionHandlers> </add> </exceptionTypes> </add> |
图3 |