ILGenerator 捕获异常不起作用
我使用 System.Reflection.Emit 生成类型的包装器。在某一时刻,原始对象可能会在访问时抛出错误 ( FaultException
),并且该错误应该由我的 try { } catch (Exception e) { }
捕获我已经实现了,但它没有。
ILSpy 正确显示了代码。
try
{
if (original.Station != null)
{
if (objectDictionary.ContainsKey(original.Station))
{
this.Station = (objectDictionary[original.Station] as StationWrapper);
}
else
{
this.Station = new StationWrapper(original.Station, objectDictionary);
}
}
}
catch (Exception arg_6D_0)
{
ReportManager.Log(arg_6D_0);
}
代码生成
这是汇编生成的代码。
Label ex = il.BeginExceptionBlock();
....
// Exception block end
il.Emit(OpCodes.Leave, ex);
il.BeginCatchBlock(typeof(Exception));
il.Emit(OpCodes.Call, ReportManager_Log);
il.EndExceptionBlock();
编辑
异常被用户代码捕获,但未被 IL 代码捕获。
反汇编
在这里删除了客户的一些命名空间。写入行是在最后几分钟添加的。
.try
{
IL_0019: ldarg.1
IL_001a: call instance class [...]...Station [...]...StationBase::get_Station()
IL_001f: brfalse IL_0063
IL_0024: ldarg.2
IL_0025: ldarg.1
IL_0026: call instance class [...]...Station [...]...StationBase::get_Station()
IL_002b: call instance bool class [mscorlib]System.Collections.Generic.Dictionary`2<object, object>::ContainsKey(!0)
IL_0030: brfalse IL_0051
IL_0035: ldarg.0
IL_0036: ldarg.2
IL_0037: ldarg.1
IL_0038: call instance class [...]...Station [...]...StationBase::get_Station()
IL_003d: call instance !1 class [mscorlib]System.Collections.Generic.Dictionary`2<object, object>::get_Item(!0)
IL_0042: isinst ...StationWrapper
IL_0047: call instance void ...StationBaseWrapper::set_Station(class ...StationWrapper)
IL_004c: br IL_0063
IL_0051: ldarg.0
IL_0052: ldarg.1
IL_0053: call instance class [...]...Station [...]...StationBase::get_Station()
IL_0058: ldarg.2
IL_0059: newobj instance void ....StationWrapper::.ctor(class [...]...Station, class [mscorlib]System.Collections.Generic.Dictionary`2<object, object>)
IL_005e: call instance void ...StationBaseWrapper::set_Station(class ...StationWrapper)
IL_0063: leave IL_007c
} // end .try
catch [mscorlib]System.Exception
{
IL_0068: ldstr "Its comming home"
IL_006d: call void [mscorlib]System.Console::WriteLine(string)
IL_0072: call void [...Report]...ReportManager::Log(class [mscorlib]System.Exception)
IL_0077: leave IL_007c
} // end handler
编辑 2
在 IL 代码中引发 System.Exception
时,在发生 FaultException'1
之前,将处理异常。使用Exception
和ArgumentException
进行测试。
I'm generating wrappers for types by using System.Reflection.Emit
. At one point it's possible that the original object is throwing a error on access ( FaultException
) and the error should be catched by my try { } catch (Exception e) { }
which i have implemented, but it does not.
The code is shown correcly by ILSpy.
try
{
if (original.Station != null)
{
if (objectDictionary.ContainsKey(original.Station))
{
this.Station = (objectDictionary[original.Station] as StationWrapper);
}
else
{
this.Station = new StationWrapper(original.Station, objectDictionary);
}
}
}
catch (Exception arg_6D_0)
{
ReportManager.Log(arg_6D_0);
}
Code generation
This is the code for the assembly-generation.
Label ex = il.BeginExceptionBlock();
....
// Exception block end
il.Emit(OpCodes.Leave, ex);
il.BeginCatchBlock(typeof(Exception));
il.Emit(OpCodes.Call, ReportManager_Log);
il.EndExceptionBlock();
Edit
The exception is getting caught by user code but not by IL-Code.
Disassembly
Removed some namespaces of the customer here. The write line has been added the last minutes.
.try
{
IL_0019: ldarg.1
IL_001a: call instance class [...]...Station [...]...StationBase::get_Station()
IL_001f: brfalse IL_0063
IL_0024: ldarg.2
IL_0025: ldarg.1
IL_0026: call instance class [...]...Station [...]...StationBase::get_Station()
IL_002b: call instance bool class [mscorlib]System.Collections.Generic.Dictionary`2<object, object>::ContainsKey(!0)
IL_0030: brfalse IL_0051
IL_0035: ldarg.0
IL_0036: ldarg.2
IL_0037: ldarg.1
IL_0038: call instance class [...]...Station [...]...StationBase::get_Station()
IL_003d: call instance !1 class [mscorlib]System.Collections.Generic.Dictionary`2<object, object>::get_Item(!0)
IL_0042: isinst ...StationWrapper
IL_0047: call instance void ...StationBaseWrapper::set_Station(class ...StationWrapper)
IL_004c: br IL_0063
IL_0051: ldarg.0
IL_0052: ldarg.1
IL_0053: call instance class [...]...Station [...]...StationBase::get_Station()
IL_0058: ldarg.2
IL_0059: newobj instance void ....StationWrapper::.ctor(class [...]...Station, class [mscorlib]System.Collections.Generic.Dictionary`2<object, object>)
IL_005e: call instance void ...StationBaseWrapper::set_Station(class ...StationWrapper)
IL_0063: leave IL_007c
} // end .try
catch [mscorlib]System.Exception
{
IL_0068: ldstr "Its comming home"
IL_006d: call void [mscorlib]System.Console::WriteLine(string)
IL_0072: call void [...Report]...ReportManager::Log(class [mscorlib]System.Exception)
IL_0077: leave IL_007c
} // end handler
Edit 2
When throwing a System.Exception
in IL code, before the FaultException'1
can occur, the exception is getting handled. Tested with Exception
and ArgumentException
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这里一切正常;你确定它不是一个嵌套的异常块?
例子:
All works fine here; are you sure it isn't a nested exception block?
Example:
这实际上似乎是 Visual-Studio 2010 的一个错误。当捕获时,VS 中的所有异常都会被忽略,但 VS 无论如何都会显示异常。
并非所有异常都会被忽略,这似乎取决于引发异常的代码。
生成的异常(通过 Emit )将被忽略,来自外部 DLL 的异常不会被忽略。
This is actually seems to be a Visual-Studio 2010 bug. All exceptions are ignored in VS when catched, but VS shows the exception anyway.
Not all exceptions are ignored, this seems to depend on the code which throws the exception.
Generated exceptions ( via Emit ) are ignored, exceptions which are from a outside DLL are not ignored.