Question

Je génère des emballages pour les types en utilisant System.Reflection.Emit. À un moment donné, il est possible que l'objet d'origine lance une erreur sur l'accès ( FaultException ) et l'erreur doit être prise par mon try { } catch (Exception e) { } Ce que j'ai mis en œuvre, mais ce n'est pas le cas.

Le code est indiquéralement par 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);
}

Génération de code

Ceci est le code de la génération d'assembly.

Label ex = il.BeginExceptionBlock();
....
// Exception block end
il.Emit(OpCodes.Leave, ex);
il.BeginCatchBlock(typeof(Exception));
il.Emit(OpCodes.Call, ReportManager_Log);
il.EndExceptionBlock();

Éditer

L'exception consiste à être capturé par le code utilisateur mais pas par le code IL.

Démontage

Supprimé certains espaces de noms du client ici. La ligne d'écriture a été ajoutée les dernières 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

Modifier 2

Lorsque vous jetez un System.Exception en code IL, avant le FaultException'1 Peut se produire, l'exception est gérée. Testé avec Exception et ArgumentException.

Était-ce utile?

La solution 2

Cela semble en fait être un bug visuel-studio 2010. Toutes les exceptions sont ignorées dans VS lorsqu'elles sont prises, mais VS montre l'exception de toute façon.

Toutes les exceptions ne sont pas ignorées, cela semble dépendre du code qui lance l'exception. Les exceptions générées (via EMIT) sont ignorées, les exceptions qui proviennent d'une DLL extérieure ne sont pas ignorées.

Autres conseils

Tout fonctionne bien ici; Êtes-vous sûr que ce n'est pas un bloc d'exception imbriqué?

Exemple:

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);
    }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top