如何在使用发出的IL代码时禁止“我的代码”对话框?

时间:2016-04-22 22:59:24

标签: c# .net visual-studio exception-handling reflection.emit

我发出了一些调用用户代码的IL代码。我将我的IL代码(来自用户代码)的调用包装在try / catch块中,以捕获其中发生的任何异常。内部用户代码抛出一个Exception,由外部用户代码的try / catch块正确捕获。这一切都是所希望的。

然而,当我打开Just My Code时,调试器会破坏我的内部用户代码首先抛出异常的位置。这是不受欢迎的行为 - 内部代码包含在try / catch中(通过发出的IL),因此它被处理,我不希望弹出Exception对话框。

我怀疑对话框正在弹出,因为Exception正在从用户代码(InternalMethod)传递到“非用户代码”(发出的IL),因为发出的IL在调用堆栈中显示为“[External code]” 。是否可以将发出的IL代码标记为用户代码,以便Exception通过而不会导致Just My Code显示Exception对话框?

using System;
using System.Reflection;
using System.Reflection.Emit;
using System.Threading;

namespace ExceptionInEmitDemo
{
    public class Program
    {
        static void Main(string[] args)
        {
            var internalMethod = typeof(Program).GetMethod("InternalMethod", BindingFlags.Public | BindingFlags.Static);

            var assembly = Thread.GetDomain().DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.Run);
            var moduleBuilder = assembly.DefineDynamicModule("DynamicModule", false);
            var typeBuilder = moduleBuilder.DefineType("DynamicType");
            var methodBuilder = typeBuilder.DefineMethod("DynamicMethod", MethodAttributes.Public | MethodAttributes.Static, typeof(void), new Type[] { });
            var ilGen = methodBuilder.GetILGenerator();
            ilGen.Emit(OpCodes.Call, internalMethod);
            ilGen.Emit(OpCodes.Ret);
            var dynamicType = typeBuilder.CreateType();

            MethodInfo dynamicMethod = dynamicType.GetMethod("DynamicMethod");
            try
            {
                dynamicMethod.Invoke(null, new object[] { });
            }
            catch (TargetInvocationException ex)
            {
                Console.WriteLine("Caught Exception: " + ex.InnerException);
            }
        }

        public static void InternalMethod()
        {
            throw new Exception("This Exception will be caught in the try/catch block");
        }
    }
}

1 个答案:

答案 0 :(得分:1)

我认为问题可能是涉及更多外部代码,MethodInfo.Invoke()方法代码。

您可以在调用的方法中添加DebuggerNonUserCodeAttribute,但这很可能不可行。

或者您可以创建目标方法的委托。

try
{
    var d = (Action)dynamicMethod.CreateDelegate(typeof(Action));
    d();
}
catch (Exception ex)
{
    Console.WriteLine("Caught Exception: " + ex);
}