使用发出的 IL 代码时,如何取消“仅我的代码”对话框?
How can I suppress the Just My Code dialog when using emitted IL code?
我发出了一些调用用户代码的 IL 代码。我将 IL 代码(来自用户代码)的调用包装在 try/catch 块中,以捕获其中发生的任何异常。内部用户代码抛出一个异常,该异常被外部用户代码的 try/catch 块正确捕获。一切如愿。
但是,当我打开“仅我的代码”时,调试器在我的内部用户代码首先抛出异常的地方中断。这是不受欢迎的行为——内部代码被包装在 try/catch 中(通过发出的 IL),因此它被处理并且我不希望弹出异常对话框。
我怀疑弹出对话框是因为异常从用户代码(InternalMethod)传递到 "non-user code"(发出的 IL),因为发出的 IL 在调用中显示为“[外部代码]”堆。是否可以将发出的 IL 代码标记为用户代码,以便异常通过而不会导致 Just My Code 显示异常对话框?
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");
}
}
}
我认为问题可能是涉及更多的外部代码,MethodInfo.Invoke()
方法代码。
您可以向调用的方法添加 DebuggerNonUserCodeAttribute
,但这很可能不可行。
或者您可以创建目标方法的委托。
try
{
var d = (Action)dynamicMethod.CreateDelegate(typeof(Action));
d();
}
catch (Exception ex)
{
Console.WriteLine("Caught Exception: " + ex);
}
我发出了一些调用用户代码的 IL 代码。我将 IL 代码(来自用户代码)的调用包装在 try/catch 块中,以捕获其中发生的任何异常。内部用户代码抛出一个异常,该异常被外部用户代码的 try/catch 块正确捕获。一切如愿。
但是,当我打开“仅我的代码”时,调试器在我的内部用户代码首先抛出异常的地方中断。这是不受欢迎的行为——内部代码被包装在 try/catch 中(通过发出的 IL),因此它被处理并且我不希望弹出异常对话框。
我怀疑弹出对话框是因为异常从用户代码(InternalMethod)传递到 "non-user code"(发出的 IL),因为发出的 IL 在调用中显示为“[外部代码]”堆。是否可以将发出的 IL 代码标记为用户代码,以便异常通过而不会导致 Just My Code 显示异常对话框?
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");
}
}
}
我认为问题可能是涉及更多的外部代码,MethodInfo.Invoke()
方法代码。
您可以向调用的方法添加 DebuggerNonUserCodeAttribute
,但这很可能不可行。
或者您可以创建目标方法的委托。
try
{
var d = (Action)dynamicMethod.CreateDelegate(typeof(Action));
d();
}
catch (Exception ex)
{
Console.WriteLine("Caught Exception: " + ex);
}