我正在使用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-Code捕获。
在此处删除了客户的一些名称空间。写行已在最后几分钟添加。
.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
在IL代码中抛出System.Exception
时,在FaultException'1
发生之前,异常就会被处理掉。使用Exception
和ArgumentException
进行了测试。
答案 0 :(得分:6)
这里一切正常;你确定它不是嵌套的异常块吗?
示例:
using System;
using System.Reflection.Emit;
public class Test
{
static void Main()
{
var dm = new DynamicMethod("foo", null, new[] {typeof(bool)});
var il = dm.GetILGenerator();
Label ex = il.BeginExceptionBlock();
il.Emit(OpCodes.Ldarg_0);
il.EmitCall(OpCodes.Call, typeof(Test).GetMethod("Throw"), null);
il.Emit(OpCodes.Leave, ex);
il.BeginCatchBlock(typeof(Exception));
il.EmitCall(OpCodes.Call, typeof(Test).GetMethod("Log"), null);
il.EndExceptionBlock();
il.Emit(OpCodes.Ldstr, "done");
il.EmitCall(OpCodes.Call, typeof(Console).GetMethod("WriteLine",
new[] {typeof(string)}), null);
il.Emit(OpCodes.Ret);
var act = (Action<bool>)dm.CreateDelegate(typeof (Action<bool>));
Console.WriteLine("Expect success:");
act(false);
Console.WriteLine("Expect fail:");
act(true);
Console.WriteLine("(all done)");
}
public static void Throw(bool fatal)
{
if(fatal) throw new InvalidOperationException("Boom!");
}
public static void Log(Exception ex)
{
Console.WriteLine("Error: " + ex.Message);
}
}
答案 1 :(得分:0)
这实际上似乎是一个Visual-Studio 2010错误。在捕获时,VS中会忽略所有异常,但VS无论如何都会显示异常。
并非所有异常都被忽略,这似乎取决于抛出异常的代码。 忽略生成的异常(通过Emit),不会忽略来自外部DLL的异常。