【Emit基础】在IL中进行异常处理
来源:互联网 发布:app后台管理系统源码 编辑:程序博客网 时间:2024/06/16 21:40
本文通过一个简单的示例来说明在IL中进行异常处理时要注意的关键点。
我们来看一个包含try...catch...finally的示例:
{
TransactionScopeFactory factory = new TransactionScopeFactory(null);
TransactionScope scope = factory.NewTransactionScope(false);
try
{
scope.Commit();
}
catch (Exception ee)
{
string msg = ee.Message;
}
finally
{
scope.Dispose();
}
}
这段代码实际上与使用using是等价的:
{
TransactionScopeFactory factory = new TransactionScopeFactory(null);
using (TransactionScope scope = factory.NewTransactionScope(false))
{
try
{
scope.Commit();
}
catch (Exception ee)
{
string msg = ee.Message;
}
}
}
它们对应的IL代码如下所示:
{
.maxstack 2
.locals init (
[0] class [DataRabbit.Application]DataRabbit.Application.TransactionScopeFactory factory,
[1] class [DataRabbit.Application]DataRabbit.Application.TransactionScope scope,
[2] class [mscorlib]System.Exception ee,
[3] string msg)
L_0000: nop
L_0001: ldnull
L_0002: newobj instance void [DataRabbit.Application]DataRabbit.Application.TransactionScopeFactory::.ctor(class [DataRabbit]DataRabbit.DataConfiguration)
L_0007: stloc.0
L_0008: ldloc.0
L_0009: ldc.i4.0
L_000a: callvirt instance class [DataRabbit.Application]DataRabbit.Application.TransactionScope [DataRabbit.Application]DataRabbit.Application.TransactionScopeFactory::NewTransactionScope(bool)
L_000f: stloc.1
L_0010: nop
L_0011: ldloc.1
L_0012: callvirt instance void [DataRabbit.Application]DataRabbit.Application.TransactionScope::Commit()
L_0017: nop
L_0018: nop
L_0019: leave.s L_0027
L_001b: stloc.2
L_001c: nop
L_001d: ldloc.2
L_001e: callvirt instance string [mscorlib]System.Exception::get_Message()
L_0023: stloc.3
L_0024: nop
L_0025: leave.s L_0027
L_0027: nop
L_0028: leave.s L_0034
L_002a: nop
L_002b: ldloc.1
L_002c: callvirt instance void [DataRabbit.Application]DataRabbit.Application.TransactionScope::Dispose()
L_0031: nop
L_0032: nop
L_0033: endfinally
L_0034: nop
L_0035: ret
.try L_0010 to L_001b catch [mscorlib]System.Exception handler L_001b to L_0027
.try L_0010 to L_002a finally handler L_002a to L_0034
}
我们来剖析这段IL中的异常处理流程:
1.有最后的两句代码,我们看到:
(1)try...catch...finally 是由try...catch 和 try...finally两部分构成。
(2)try...finally 中的try块内含了catch块。
即类似这样:
{
.try
{
}
catch
{
}
}
finally
{
}
2.try块、catch块(catch handler)只能通过leave(或leave.s)退出。
3.finally块(finally handler)必须通过endfinally退出。
4.由于try...catch 和 try...finally两部分都需要退出try块,所以我们看到在L_0019 和 L_0028 处都有对应的leave.s指令。
5.程序中如果没有finally块,则IL中只需要处理try...catch 部分;同理,如果程序中没有catch块,则IL只需要处理try...finally部分。
6.总结起来,IL的异常处理类似这个样子:
.try
{
.try
{
leave L1
}
catch
{
leave L1
}
leave L2
}
finally
{
endfinally
}
- 【Emit基础】在IL中进行异常处理
- 利用RunSharp替代Reflaction.Emit进行IL处理
- 【Emit基础】IL中发布、订阅、触发事件
- 如何在Application中进行异常处理
- 【Emit基础】IL定义方法的语法详解
- 【Emit基础】调用Tostring()方法的IL表示
- 在使用SSH过程中,在JSP页面中对数据进行处理,出异常!
- 在服务器端进行异常处理方法
- IL,Emit之OpCodes说明(备查)
- C# 异常处理(Catch Throw)IL分析
- 在进行jpa更新操作中报异常Cascade="All-Delete-Orphan" 处理
- 养成在程序中对可能出现的异常进行处理的习惯
- “System.Reflection.TargetInvocationException”类型的异常在 mscorlib.dll 中发生,但未在用户代码中进行处理
- “System.ArgumentNullException”类型的异常在 mscorlib.dll 中发生,但未在用户代码中进行处理
- “System.IndexOutOfRangeException”类型的异常在 Stores.dll 中发生,但未在用户代码中进行处理
- “System.TypeInitializationException”类型的异常在 EntityFramework.dll 中发生,但未在用户代码中进行处理
- System.Resources.MissingManifestResourceException”类型的异常在 mscorlib.dll 中发生,但未在用户代码中进行处理
- javascript 进行异常处理
- A*算法的C#实现
- DataRabbit 轻量的ORM框架(17)-- 使用DataRabbit的最佳实践
- 【Emit基础】IL中发布、订阅、触发事件
- 【Emit基础】IL定义方法的语法详解
- 新人第一贴!
- 【Emit基础】在IL中进行异常处理
- 【Emit基础】调用Tostring()方法的IL表示
- 【Emit基础】OpCodes.Ldind_Ref 和 OpCodes.Ldind_I*
- 【Emit基础】System.AccessViolationException: 尝试读取或写入受保护的内存。这通常指示其他内存已损坏。
- Strive 2D游戏引擎 -- 序
- 高性能的大型系统经验 -- 将数据分类、并缓存
- Remoting插件与网关设置
- Spring.net -- 目前不支持getter、setter的访问限定符
- DataRabbit 轻量的ORM框架(16)-- Entity缓存