Enterprise Library Step By Step
系列(十二):异常处理应用程序块——进阶篇
作者:Terrylee
一.把异常信息Logging到数据库
在日志和监测应用程序块中,有朋友提意见说希望能够把异常信息Logging到数据库中,在这里介绍一下具体的实现方法。
1.创建相关的数据库环境:
我们可以用日志和监测应用程序块自带的SQL语句来创建相关的数据库环境:
创建数据库:
CREATE
DATABASE
[
Logging
]
ON
(NAME
=
N
'
Logging
'
, FILENAME
=
N
'
C:\Program Files\Microsoft SQL Server\MSSQL\data\Logging.mdf
'
, SIZE
=
1
, FILEGROWTH
=
10
%
)
LOG
ON
(NAME
=
N
'
Logging_log
'
, FILENAME
=
N
'
C:\Program Files\Microsoft SQL Server\MSSQL\data\Logging_log.LDF
'
, FILEGROWTH
=
10
%
)
创建表:
CREATE
TABLE
[
dbo
]
.
[
Log
]
(
[
LogID
]
[
int
]
IDENTITY
(
1
,
1
)
NOT
NULL
,
[
EventID
]
[
int
]
NULL
,
[
Category
]
[
nvarchar
]
(
64
) COLLATE SQL_Latin1_General_CP1_CI_AS
NOT
NULL
,
[
Priority
]
[
int
]
NOT
NULL
,
[
Severity
]
[
nvarchar
]
(
32
) COLLATE SQL_Latin1_General_CP1_CI_AS
NOT
NULL
,
[
Title
]
[
nvarchar
]
(
256
) COLLATE SQL_Latin1_General_CP1_CI_AS
NOT
NULL
,
[
Timestamp
]
[
datetime
]
NOT
NULL
,
[
MachineName
]
[
nvarchar
]
(
32
) COLLATE SQL_Latin1_General_CP1_CI_AS
NOT
NULL
,
[
AppDomainName
]
[
nvarchar
]
(
2048
) COLLATE SQL_Latin1_General_CP1_CI_AS
NOT
NULL
,
[
ProcessID
]
[
nvarchar
]
(
256
) COLLATE SQL_Latin1_General_CP1_CI_AS
NOT
NULL
,
[
ProcessName
]
[
nvarchar
]
(
2048
) COLLATE SQL_Latin1_General_CP1_CI_AS
NOT
NULL
,
[
ThreadName
]
[
nvarchar
]
(
2048
) COLLATE SQL_Latin1_General_CP1_CI_AS
NULL
,
[
Win32ThreadId
]
[
nvarchar
]
(
128
) COLLATE SQL_Latin1_General_CP1_CI_AS
NULL
,
[
Message
]
[
nvarchar
]
(
2048
) COLLATE SQL_Latin1_General_CP1_CI_AS
NULL
,
[
FormattedMessage
]
[
ntext
]
COLLATE SQL_Latin1_General_CP1_CI_AS
NULL
)
ON
[
PRIMARY
]
TEXTIMAGE_ON
[
PRIMARY
]
GO
创建存储过程:
1
CREATE
PROCEDURE
WriteLog
2
(
3
@EventID
int
,
4
@Category
nvarchar
(
64
),
5
@Priority
int
,
6
@Severity
nvarchar
(
32
),
7
@Title
nvarchar
(
256
),
8
@Timestamp
datetime
,
9
@MachineName
nvarchar
(
32
),
10
@AppDomainName
nvarchar
(
2048
),
11
@ProcessID
nvarchar
(
256
),
12
@ProcessName
nvarchar
(
2048
),
13
@ThreadName
nvarchar
(
2048
),
14
@Win32ThreadId
nvarchar
(
128
),
15
@Message
nvarchar
(
2048
),
16
@FormattedMessage
ntext
17
)
18
AS
19
![Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇 Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇](https://image.shishitao.com:8440/aHR0cHM6Ly93d3cuaXRkYWFuLmNvbS9nby9MMGx0WVdkbGN5OVBkWFJzYVc1cGJtZEpibVJwWTJGMGIzSnpMMDV2Ym1VdVoybG0%3D.jpg?w=700&webp=1)
20
INSERT
INTO
[
Log
]
(
21
EventID,
22
Category,
23
Priority,
24
Severity,
25
Title,
26
[
Timestamp
]
,
27
MachineName,
28
AppDomainName,
29
ProcessID,
30
ProcessName,
31
ThreadName,
32
Win32ThreadId,
33
Message,
34
FormattedMessage
35
)
36
VALUES
(
37
@EventID
,
38
@Category
,
39
@Priority
,
40
@Severity
,
41
@Title
,
42
@Timestamp
,
43
@MachineName
,
44
@AppDomainName
,
45
@ProcessID
,
46
@ProcessName
,
47
@ThreadName
,
48
@Win32ThreadId
,
49
@Message
,
50
@FormattedMessage
)
51
GO
该SQL语句默认的路径为C:\Program Files\Microsoft Enterprise Library\src\Logging\Sinks\Database\Scripts,直接运行CreateLoggingDatabase.cmd即可。
2.运行配置工具,我们创建一个日志和监测应用程序块,并建一个Database Sink,具体的配置方法在日志和监测应用程序块中讲过了,这里就不重复了,我们看一下它的配置:
![Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇 Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇](https://image.shishitao.com:8440/aHR0cHM6Ly93d3cuaXRkYWFuLmNvbS9pbWdzLzcvMi8zLzMvNTkvZDQwN2YyZjk5NzhjNTZmOTZlNWM2NmQ1MThkM2U2MGEuanBl.jpe?w=700&webp=1)
注意设置StoredProcName为WriteLog,就是我们刚才创建的存储过程。
3.同时再创建一个Category,起名为DataException,并设置它的Sink为Database Sink。
4.设置Logging Handler的LogCategory为我们刚才创建的DataException,其他的参数暂时默认。
![Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇 Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇](https://image.shishitao.com:8440/aHR0cHM6Ly93d3cuaXRkYWFuLmNvbS9pbWdzLzEvNS8yLzAvOTAvOTk3YmIyY2NjMDQyNGFmZTdiNGI1YTQxZWY5OGE5MDMuanBl.jpe?w=700&webp=1)
5.至此配置完成,在程序中我们不需要做任何改动(这就是企业库的配置驱动的思想精妙之处^_^)。
1
![Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇 Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇](https://image.shishitao.com:8440/aHR0cHM6Ly93d3cuaXRkYWFuLmNvbS9nby9MMGx0WVdkbGN5OVBkWFJzYVc1cGJtZEpibVJwWTJGMGIzSnpMMFY0Y0dGdVpHVmtRbXh2WTJ0VGRHRnlkQzVuYVdZPQ%3D%3D.jpg?w=700&webp=1)
/**/
/// <summary>
2
/// 日志策略
3
/// </summary>
4
/// <param name="sender"></param>
5
/// <param name="e"></param>
6
private
void
btn_Log_Click(
object
sender, System.EventArgs e)
7
![Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇 Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇](https://image.shishitao.com:8440/aHR0cHM6Ly93d3cuaXRkYWFuLmNvbS9nby9MMGx0WVdkbGN5OVBkWFJzYVc1cGJtZEpibVJwWTJGMGIzSnpMMFY0Y0dGdVpHVmtRbXh2WTJ0VGRHRnlkQzVuYVdZPQ%3D%3D.jpg?w=700&webp=1)
{
8
try
9![Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇 Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇](https://image.shishitao.com:8440/aHR0cHM6Ly93d3cuaXRkYWFuLmNvbS9nby9MMGx0WVdkbGN5OVBkWFJzYVc1cGJtZEpibVJwWTJGMGIzSnpMMFY0Y0dGdVpHVmtVM1ZpUW14dlkydFRkR0Z5ZEM1bmFXWT0%3D.jpg?w=700&webp=1)
{
10
Exception ex = new Exception();
11
throw ex;
12
}
13
catch(Exception ex)
14![Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇 Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇](https://image.shishitao.com:8440/aHR0cHM6Ly93d3cuaXRkYWFuLmNvbS9nby9MMGx0WVdkbGN5OVBkWFJzYVc1cGJtZEpibVJwWTJGMGIzSnpMMFY0Y0dGdVpHVmtVM1ZpUW14dlkydFRkR0Z5ZEM1bmFXWT0%3D.jpg?w=700&webp=1)
{
15
bool Flag = ExceptionPolicy.HandleException(ex,"Log Policy");
16![Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇 Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇](https://image.shishitao.com:8440/aHR0cHM6Ly93d3cuaXRkYWFuLmNvbS9nby9MMGx0WVdkbGN5OVBkWFJzYVc1cGJtZEpibVJwWTJGMGIzSnpMMGx1UW14dlkyc3VaMmxt.jpg?w=700&webp=1)
17
if(Flag)
18![Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇 Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇](https://image.shishitao.com:8440/aHR0cHM6Ly93d3cuaXRkYWFuLmNvbS9nby9MMGx0WVdkbGN5OVBkWFJzYVc1cGJtZEpibVJwWTJGMGIzSnpMMFY0Y0dGdVpHVmtVM1ZpUW14dlkydFRkR0Z5ZEM1bmFXWT0%3D.jpg?w=700&webp=1)
{
19
throw;
20
}
21
}
22
}
补充一点:在项目中要添加对Microsoft.Practices.EnterpriseLibrary.Logging.Sinks.Database.dll的引用
二.异常的传播机制
异常的传播机制有以下几种:
l 异常自动传播
l 在同一层内部,捕获或者再抛出原有异常
l 捕获,包装和抛出包装后的异常
我们不推荐直接抛出原有异常,因为恶意的用户能够从系统诊断信息中得知应用的详细情况,并从中查找应用的弱点。异常应用程序块提供了一旦配置的Handler执行后,就产生对应的post-handling动作,该动作有如下选项:
None - 没有重抛异常的动作。
NotifyRethrow - 告诉调用程序:Policy推荐应该重抛异常。
ThrowNewException - 在所有的Handler执行后,向调用程序抛出最终异常(并不一定是原始的异常)。
三.异常的格式化
可以格式化任何System.Exception类型的异常
能够用来记录或者显示异常的详细信息
字符型格式化器——TextExceptionFormatter:创建在一个屏幕上,日志中或以其他形式表现的,可以表现异常信息的详细记录
XML格式化器——XMLExceptionFormatter:针对一个异常,创建一个用XML表现形式表现记录,每一个异常的属性,均可以被存储为XML元素。
看一下在Enterprise Library Quick Start中提供的自定义的ExceptionFormatter,实现了TextExceptionFormatter类:
1
![Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇 Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇](https://image.shishitao.com:8440/aHR0cHM6Ly93d3cuaXRkYWFuLmNvbS9nby9MMGx0WVdkbGN5OVBkWFJzYVc1cGJtZEpibVJwWTJGMGIzSnpMMFY0Y0dGdVpHVmtRbXh2WTJ0VGRHRnlkQzVuYVdZPQ%3D%3D.jpg?w=700&webp=1)
/**/
/// <summary>
2
/// Summary description for AppTextExceptionFormatter.
3
/// </summary>
4
public
class
AppTextExceptionFormatter : TextExceptionFormatter
5
![Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇 Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇](https://image.shishitao.com:8440/aHR0cHM6Ly93d3cuaXRkYWFuLmNvbS9nby9MMGx0WVdkbGN5OVBkWFJzYVc1cGJtZEpibVJwWTJGMGIzSnpMMFY0Y0dGdVpHVmtRbXh2WTJ0VGRHRnlkQzVuYVdZPQ%3D%3D.jpg?w=700&webp=1)
{
6
public AppTextExceptionFormatter(TextWriter writer, Exception exception)
7
: base (writer, exception)
8![Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇 Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇](https://image.shishitao.com:8440/aHR0cHM6Ly93d3cuaXRkYWFuLmNvbS9nby9MMGx0WVdkbGN5OVBkWFJzYVc1cGJtZEpibVJwWTJGMGIzSnpMMFY0Y0dGdVpHVmtVM1ZpUW14dlkydFRkR0Z5ZEM1bmFXWT0%3D.jpg?w=700&webp=1)
{
9
}
10
11
protected override void WriteDescription()
12![Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇 Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇](https://image.shishitao.com:8440/aHR0cHM6Ly93d3cuaXRkYWFuLmNvbS9nby9MMGx0WVdkbGN5OVBkWFJzYVc1cGJtZEpibVJwWTJGMGIzSnpMMFY0Y0dGdVpHVmtVM1ZpUW14dlkydFRkR0Z5ZEM1bmFXWT0%3D.jpg?w=700&webp=1)
{
13
// An exception of type {0} occurred and was caught.
14
string line = String.Format("An exception of type {0} occurred and was caught.", base.Exception.GetType().FullName);
15
this.Writer.WriteLine(line);
16
}
17![Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇 Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇](https://image.shishitao.com:8440/aHR0cHM6Ly93d3cuaXRkYWFuLmNvbS9nby9MMGx0WVdkbGN5OVBkWFJzYVc1cGJtZEpibVJwWTJGMGIzSnpMMGx1UW14dlkyc3VaMmxt.jpg?w=700&webp=1)
18
protected override void WriteExceptionType(Type exceptionType)
19![Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇 Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇](https://image.shishitao.com:8440/aHR0cHM6Ly93d3cuaXRkYWFuLmNvbS9nby9MMGx0WVdkbGN5OVBkWFJzYVc1cGJtZEpibVJwWTJGMGIzSnpMMFY0Y0dGdVpHVmtVM1ZpUW14dlkydFRkR0Z5ZEM1bmFXWT0%3D.jpg?w=700&webp=1)
{
20
base.Indent();
21
base.Writer.WriteLine("Type : {0}", exceptionType.FullName);
22
}
23![Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇 Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇](https://image.shishitao.com:8440/aHR0cHM6Ly93d3cuaXRkYWFuLmNvbS9nby9MMGx0WVdkbGN5OVBkWFJzYVc1cGJtZEpibVJwWTJGMGIzSnpMMGx1UW14dlkyc3VaMmxt.jpg?w=700&webp=1)
24
public override void Format()
25![Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇 Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇](https://image.shishitao.com:8440/aHR0cHM6Ly93d3cuaXRkYWFuLmNvbS9nby9MMGx0WVdkbGN5OVBkWFJzYVc1cGJtZEpibVJwWTJGMGIzSnpMMFY0Y0dGdVpHVmtVM1ZpUW14dlkydFRkR0Z5ZEM1bmFXWT0%3D.jpg?w=700&webp=1)
{
26
//this.Writer.WriteLine("Message : {0}", message);
27
this.WriteDescription();
28
//this.WriteExceptionType(base.Exception.GetType());
29
base.WriteMessage(base.Exception.Message);
30
}
31![Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇 Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇](https://image.shishitao.com:8440/aHR0cHM6Ly93d3cuaXRkYWFuLmNvbS9nby9MMGx0WVdkbGN5OVBkWFJzYVc1cGJtZEpibVJwWTJGMGIzSnpMMGx1UW14dlkyc3VaMmxt.jpg?w=700&webp=1)
32
}
四.创建自定义的异常处理器
异常处理应用程序块允许您包装并使用您自己的例外业务处理流程,例如在时间记录系统中填写一个事件,利用业务规范进行包装和替代,利用另外的记录系统进行记录(比较常用的有Log4net,前段时间深渊野鱼介绍的,还没用过^_^),这种灵活的可配置性,将允许您在不同的异常类型及其策略中灵活的配置。
可以通过实现ExceptionHandler抽象类,来创建定制的Handler
1
public
abstract
class
ExceptionHandler : ConfigurationProvider, IExceptionHandler
该抽象类继承ConfigurationProvider类,并实现IExceptionHandler接口。ConfigurationProvider抽象类实现了IConfigurationProvider接口,用来读取配置数据。
1
public
abstract
class
ConfigurationProvider : IConfigurationProvider
使用支持序列化的数据类型作为配置参数,还有要注意数据类型的简单,避免“Exception Handling Exceptions”
看一下在Enterprise Library Quick Start中提供了定制Handler的实现:
1
![Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇 Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇](https://image.shishitao.com:8440/aHR0cHM6Ly93d3cuaXRkYWFuLmNvbS9nby9MMGx0WVdkbGN5OVBkWFJzYVc1cGJtZEpibVJwWTJGMGIzSnpMMFY0Y0dGdVpHVmtRbXh2WTJ0VGRHRnlkQzVuYVdZPQ%3D%3D.jpg?w=700&webp=1)
/**/
/// <summary>
2
/// Summary description for GlobalPolicyExceptionHandler.
3
/// </summary>
4
public
class
AppMessageExceptionHandler : ExceptionHandler
5
![Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇 Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇](https://image.shishitao.com:8440/aHR0cHM6Ly93d3cuaXRkYWFuLmNvbS9nby9MMGx0WVdkbGN5OVBkWFJzYVc1cGJtZEpibVJwWTJGMGIzSnpMMFY0Y0dGdVpHVmtRbXh2WTJ0VGRHRnlkQzVuYVdZPQ%3D%3D.jpg?w=700&webp=1)
{
6
public AppMessageExceptionHandler()
7![Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇 Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇](https://image.shishitao.com:8440/aHR0cHM6Ly93d3cuaXRkYWFuLmNvbS9nby9MMGx0WVdkbGN5OVBkWFJzYVc1cGJtZEpibVJwWTJGMGIzSnpMMFY0Y0dGdVpHVmtVM1ZpUW14dlkydFRkR0Z5ZEM1bmFXWT0%3D.jpg?w=700&webp=1)
{
8
}
9![Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇 Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇](https://image.shishitao.com:8440/aHR0cHM6Ly93d3cuaXRkYWFuLmNvbS9nby9MMGx0WVdkbGN5OVBkWFJzYVc1cGJtZEpibVJwWTJGMGIzSnpMMGx1UW14dlkyc3VaMmxt.jpg?w=700&webp=1)
10
public override void Initialize(ConfigurationView configurationView)
11![Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇 Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇](https://image.shishitao.com:8440/aHR0cHM6Ly93d3cuaXRkYWFuLmNvbS9nby9MMGx0WVdkbGN5OVBkWFJzYVc1cGJtZEpibVJwWTJGMGIzSnpMMFY0Y0dGdVpHVmtVM1ZpUW14dlkydFRkR0Z5ZEM1bmFXWT0%3D.jpg?w=700&webp=1)
{
12
}
13![Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇 Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇](https://image.shishitao.com:8440/aHR0cHM6Ly93d3cuaXRkYWFuLmNvbS9nby9MMGx0WVdkbGN5OVBkWFJzYVc1cGJtZEpibVJwWTJGMGIzSnpMMGx1UW14dlkyc3VaMmxt.jpg?w=700&webp=1)
14
public override Exception HandleException(Exception exception, string policyName, Guid correlationID)
15![Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇 Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇](https://image.shishitao.com:8440/aHR0cHM6Ly93d3cuaXRkYWFuLmNvbS9nby9MMGx0WVdkbGN5OVBkWFJzYVc1cGJtZEpibVJwWTJGMGIzSnpMMFY0Y0dGdVpHVmtVM1ZpUW14dlkydFRkR0Z5ZEM1bmFXWT0%3D.jpg?w=700&webp=1)
{
16
DialogResult result = this.ShowThreadExceptionDialog(exception);
17![Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇 Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇](https://image.shishitao.com:8440/aHR0cHM6Ly93d3cuaXRkYWFuLmNvbS9nby9MMGx0WVdkbGN5OVBkWFJzYVc1cGJtZEpibVJwWTJGMGIzSnpMMGx1UW14dlkyc3VaMmxt.jpg?w=700&webp=1)
18
// Exits the program when the user clicks Abort.
19
if (result == DialogResult.Abort)
20
Application.Exit();
21![Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇 Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇](https://image.shishitao.com:8440/aHR0cHM6Ly93d3cuaXRkYWFuLmNvbS9nby9MMGx0WVdkbGN5OVBkWFJzYVc1cGJtZEpibVJwWTJGMGIzSnpMMGx1UW14dlkyc3VaMmxt.jpg?w=700&webp=1)
22
return exception;
23
}
24![Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇 Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇](https://image.shishitao.com:8440/aHR0cHM6Ly93d3cuaXRkYWFuLmNvbS9nby9MMGx0WVdkbGN5OVBkWFJzYVc1cGJtZEpibVJwWTJGMGIzSnpMMGx1UW14dlkyc3VaMmxt.jpg?w=700&webp=1)
25
// Creates the error message and displays it.
26
private DialogResult ShowThreadExceptionDialog(Exception e)
27![Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇 Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇](https://image.shishitao.com:8440/aHR0cHM6Ly93d3cuaXRkYWFuLmNvbS9nby9MMGx0WVdkbGN5OVBkWFJzYVc1cGJtZEpibVJwWTJGMGIzSnpMMFY0Y0dGdVpHVmtVM1ZpUW14dlkydFRkR0Z5ZEM1bmFXWT0%3D.jpg?w=700&webp=1)
{
28
string errorMsg = e.Message + Environment.NewLine + Environment.NewLine;
29![Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇 Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇](https://image.shishitao.com:8440/aHR0cHM6Ly93d3cuaXRkYWFuLmNvbS9nby9MMGx0WVdkbGN5OVBkWFJzYVc1cGJtZEpibVJwWTJGMGIzSnpMMGx1UW14dlkyc3VaMmxt.jpg?w=700&webp=1)
30
return MessageBox.Show(errorMsg, "Application Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
31
}
32
}
结束语:异常处理应用程序块的进阶篇就写到这里了。