企业库异常处理块(Enterprise Library Exception Handling Block)提供了处理异常所需的所有基本代码
现在
你可以不用再编写这些重复性的异常处理代码
只需简单地在程序中使用它们
就可保证一致且高效地异常处理
在一个理想的程序世界中编写的所有代码都是运行无误的但现实是无论你在编写代码时多么地小心错误总会发生所以必须要有一个高效可配置的框架(framework)以一种优雅方式来处理错误另外也必须要懂得人们通常以对程序的用户体验带来多大影响来衡量一种异常处理的有效性因此一个好的异常处理解决方案不单是从用户的观点优雅地处理错误而且还可通过开发者或系统管理员以可配置的错误处理行为提供健壮的配置设定这也是异常处理块的关键组成部分
与Enterprise Library 一同到来的是崭新的异常处理应用程序块自从老的异常管理应用程序块发布以来其经过了巨大的改进可从MSDN下载EntLib Caching Block获得为有效地使用你必须接受以下三个主要观点
·异常处理是在你的代码探测到有异常发生时处理异常的一个过程
·异常日志记录是记录一个异常的过程其包括发送格式化异常到事件记录器或发送一封Email而异常处理块则利用了日志记录和事件记录
·异常处理策略允许你控制异常处理和使用外部配置文件记录的行为这样就的好处是现在不用在代码中实施这样的规则了换句话来说你可在一个策略文件中定义异常处理然后在不改变代码的情况下在测试调试产品定型期间修改行为以适应不同的异常处理需要
另外使用异常处理块在探测到异常时可做以下三件事情
·你可把异常包装为一个新的异常并加入新的上下文信息或错误详细信息当新的异常传递到调用堆栈时仍可通过InnerException属性访问到原始的异常
·你可用一个新的异常取代原有异常一般来说这样做的目的是不想让原始异常的详细信息传递出程序
·你可以记录异常当然也可结合使用包装或取代的方法来达到此目的或者你可以记录原始异常并把它传递到调用堆栈
使用异常处理块
在安装完企业库(Enterprise Library)之后就可利用异常处理块开始编写代码了为正确使用异常处理块请遵循以下步骤
在你的解决方案中分别添加一个对MicrosoftPracticesEnterpriseLibraryCommondll和MicrosoftPracticesEnterpriseLibraryExceptionHandlingdll程序集的引用可使用添加引用选项并定位到X:\Program Files\Microsoft Enterprise Library January \bin文件夹如果还想使用异常处理日志记录请再添加一个对MicrosoftPracticesEnterpriseLibraryExceptionHandlingLoggingdll的引用
像如下所示在根<configuration>下的<configSections>中添加必要的项目到你的nfig(Windows Forms)或nfig(ASPNET程序)文件
<section
name=exceptionHandling
type=MicrosoftPractices
EnterpriseLibrary
ExceptionHandling
Configuration
ExceptionHandlingSettings
MicrosoftPractices
EnterpriseLibrary
ExceptionHandling />
如果随同异常处理一块使用日志记录还需要在<configSections>中加入以下设置
<section
name=loggingConfiguration
type=MicrosoftPractices
EnterpriseLibraryLogging
ConfigurationLoggingSettings
MicrosoftPractices
EnterpriseLibraryLogging />
接下来直接在<configuration>下添加<exceptionHandling>在<exceptionHandling>之内你可添加所有的异常处理策略以下的代码表示在<exceptionHandling>中指定了一个名为Global Policy的策略
<exceptionHandling>
<exceptionPolicies>
<add name=Global Policy>
<exceptionTypes>
<add name=Exception
type=SystemException
mscorlib Version=
Culture=neutral
PublicKeyToken=bace
postHandlingAction=None>
<exceptionHandlers>
<add name=Application
Message Handler
type=ExceptionMgmtBlockExample
AppMessageExceptionHandler
ExceptionMgmtBlockExample/>
</exceptionHandlers>
</add>
</exceptionTypes>
</add>
</exceptionPolicies>
</exceptionHandling>
上述的设置指定了处理所有异常的一个策略另外使用<exceptionHandlers>项你可指定一个自定义的异常处理方法其将以适当的方式处理异常在这个例子中自定义异常处理方法实现为一个名为AppMessageExceptionHandler的类而在本文的后面部分将会看到AppMessageExceptionHandler类具体的实现属性postHandlingAction指定了处理基于策略的异常的行为此属性可接受以下值NoneNotifyRethrowThrowNewException
添加这些设置最简单的方法就是使用企业库中的企业库配置工具(Enterprise Library Configuration Tool)在企业库配置工具中上述设置如图所示
图
在你的工程中引入异常处理块的核心命名空间MicrosoftPracticesEnterpriseLibraryExceptionHandling
现在就可使用上述命名空间中的类编写代码了
使用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 = ExceptionPolicyHandleException (ex Global Policy);
if (rethrow)
{
throw;
}
}
}
在try块中只是简单地抛出一个异常而catch块将会捕捉到它从而触发ExceptionPolicy类中的HandleException()方法并在其中传递了一个Golbal Policy的策略名参数正如前一节所提到的Golbal Policy与名为AppMessageExceptionHandler的异常处理方法相关联其声明如下
using System;
using SystemCollectionsSpecialized;
using SystemWindowsForms;
using MicrosoftPracticesEnterpriseLibraryCommonConfiguration;
using MicrosoftPracticesEnterpriseLibraryCommonConfigurationObjectBuilder;
using MicrosoftPracticesEnterpriseLibraryExceptionHandling;
using MicrosoftPracticesEnterpriseLibraryExceptionHandlingConfiguration;
namespace ExceptionMgmtBlockExample
{
[ConfigurationElementType (typeof(CustomHandlerData))]
public class AppMessageExceptionHandler : IExceptionHandler
{
public AppMessageExceptionHandler(NameValueCollection ignore)
{}
public Exception HandleException (Exception exception Guid correlationID)
{
DialogResult result = thisShowThreadExceptionDialog (exception);
if (result == DialogResultAbort)
ApplicationExit();
return exception;
}
private DialogResult ShowThreadExceptionDialog(Exception e)
{
string errorMsg = eMessage + EnvironmentNewLine + EnvironmentNewLine;
return MessageBoxShow(errorMsg Application Error MessageBoxButtonsOK MessageBoxIconStop);
}
}
}
正如你所看到的自定义的异常处理方法继承自IExceptionHandler接口而HandleException方法触发了另一个名为ShowThreadExceptionDialog的方法其将格式化异常信息并在屏幕上显示
如果你运行这个程序并单击Handle Exception按钮将看到图所示的消息框
图
记录一个异常
除了处理异常之外你也可对异常处理块进行配置以记录下异常正如前面所提到的可在日志记录块(Logging Block)的帮助之下完成这项工作为进行日志记录的演示再添加一个名为btnLogException的按钮并修改它的单击事件如下
private void btnLogException_Click(object sender EventArgs e)
{
try
{
throw new Exception (This is a test exception);
}
catch (Exception ex)
{
bool rethrow = ExceptionPolicyHandleException (ex Log Only Policy);
if (rethrow)
{
throw;
}
}
}
通过传递异常对象(ex)和策略(本例中为Log Only Policy)catch块将会触发ExceptionPolicyHandleException方法与异常策略类似你可在nfig或nfig文件中指定记录配置信息例如下面所示的nfig代码把Log Only Policy配置为<exceptionPolicies>下的一个子项
<add name=Log Only Policy>
<exceptionTypes>
<add name=Exception
type=SystemException mscorlib
Version= Culture=neutral
PublicKeyToken=bace
postHandlingAction=None>
<exceptionHandlers>
<add logCategory=Default Category
eventId= severity=Error
title=Exception Management
Application Exception
priority=
formatterType=Microsoft
PracticesEnterpriseLibrary
ExceptionHandlingTextExceptionFormatter
MicrosoftPracticesEnterpriseLibrary
ExceptionHandling
name=Logging Handler
type=MicrosoftPracticesEnterpriseLibrary
ExceptionHandlingLogging
LoggingExceptionHandler
MicrosoftPracticesEnterpriseLibrary
ExceptionHandlingLogging/>
</exceptionHandlers>
</add>
</exceptionTypes>
</add>
相应作为演示的目的日志记录块只是简单地在应用程序项中记录下异常如图所示
图
注意nfig文件中的记录配置信息控制着日志项的格式
从本文中你已看到异常处理块提供了一组高度复用的类由此就不必再重复编写那些操作处理记录异常的代码了通过使用这些类你可减少程序中错误bug及节省打字输入的时间集中精力在程序的核心业务逻辑上从而可极大地提高生产率