StackTrace中遗漏的编译Lambda第一个方法

时间:2016-12-14 12:15:22

标签: c# lambda expression

我们正在使用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中删除它或者我错了吗?

1 个答案:

答案 0 :(得分:0)

它没有显示,因为JIT compiler非常智能,可以内联方法调用。

您可以通过强制编译器不要内联它来阻止它,这可能会降低性能:

[MethodImpl(MethodImplOptions.NoInlining)]
public static void Method1()
{
    Method2();
}

它已经在调试构建模式下工作,因为编译器没有优化这些程序集以便于调试。