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
Когда бросали System.Exception
в коде IL, перед FaultException'1
может произойти, исключение обрабатывается. Протестировано с Exception
а также ArgumentException
,
2 ответа
На самом деле это похоже на ошибку Visual-Studio 2010. При исключении все исключения игнорируются в VS, но VS все равно показывает исключение.
Не все исключения игнорируются, похоже, это зависит от кода, который генерирует исключение. Генерируемые исключения (через Emit) игнорируются, исключения из внешней DLL не игнорируются.
Здесь все отлично работает; Вы уверены, что это не вложенный блок исключений?
Пример:
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);
}
}