我们正在使用Expression.Lambda来编译Delegates。
最近我们注意到"顶级"当抛出异常时,堆栈跟踪中缺少被绑定到目标Delegate的方法。
重现此行为的完整示例:
using System;
using System.Linq.Expressions;
using System.Reflection;
namespace Sandbox
{
public class Program
{
private static void Main()
{
var methodInfo = typeof(X).GetMethod(nameof(X.Method1), BindingFlags.Static | BindingFlags.Public);
var call = Expression.Call(methodInfo);
var compiledDelegate = Expression.Lambda<Action>(call, null).Compile();
try
{
compiledDelegate();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
Console.ReadKey();
}
public class X
{
public static void Method1()
{
Method2();
}
public static void Method2()
{
Console.WriteLine("Strange");
throw new Exception();
}
}
}
}
运行.exe( releasebuild )时,您将获得以下StackTrace
System.Exception: Eine Ausnahme vom Typ "System.Exception" wurde ausgelöst.
bei Sandbox.Program.X.Method2() in [..]\Program.cs:Zeile 38.
bei lambda_method(Closure )
bei Sandbox.Program.Main() in [..]\Program.cs:Zeile 18.
请注意,Method1缺失。
我的问题是:如何让Method1出现,为什么不出现?
Method1似乎是内联但是不应该从callstack中删除它或者我错了吗?
答案 0 :(得分:0)
它没有显示,因为JIT compiler非常智能,可以内联方法调用。
您可以通过强制编译器不要内联它来阻止它,这可能会降低性能:
[MethodImpl(MethodImplOptions.NoInlining)]
public static void Method1()
{
Method2();
}
它已经在调试构建模式下工作,因为编译器没有优化这些程序集以便于调试。