C# 用于登录.NET的堆栈跟踪

C# 用于登录.NET的堆栈跟踪,c#,.net,logging,attributes,inline,C#,.net,Logging,Attributes,Inline,我编写了一个logger/exceptionfactory模块,它使用System.Diagnostics.StackTrace从调用方法及其声明类型获取属性。然而,我注意到,如果我在visualstudio之外的发布模式下运行代码,我的一些较短的方法就会内联并从堆栈跟踪中丢失。现在我无法测试一个方法是否会在运行时内联,但我不想[MethodImpl(MethodImplOptions.noinline)]所有重要的方法。但是如果我的基类中的一个方法因此而丢失,我可能会误读层和操作信息,这可能导

我编写了一个logger/exceptionfactory模块,它使用System.Diagnostics.StackTrace从调用方法及其声明类型获取属性。然而,我注意到,如果我在visualstudio之外的发布模式下运行代码,我的一些较短的方法就会内联并从堆栈跟踪中丢失。现在我无法测试一个方法是否会在运行时内联,但我不想
[MethodImpl(MethodImplOptions.noinline)]
所有重要的方法。但是如果我的基类中的一个方法因此而丢失,我可能会误读层和操作信息,这可能导致错误的日志或参数错误的异常


是否有一个经验法则,什么内容在何时何地内联?虚拟方法、静态方法和基类方法是否有不同的处理方式?我只需要担心组件内部的内联吗?内部名称空间

是的,有一些规则,但它们是JIT编译器使用的试探法,这些试探法可以随时更改

  • 虚拟方法不能内联
  • 另一方面,接口方法可能是内联的,尽管我不能100%确定这是否会导致堆栈跟踪崩溃
  • 静态方法和非虚拟实例方法当然可以内联
  • 内联可能会跨越名称空间(当然)和程序集(不太明显),因为它发生在JIT编译方法调用时的运行时
  • “重”方法将不会内联。这取决于“重”的定义,并且是JIT应用的启发式的一部分
  • 我知道的一些关于“重”的启发式方法:

    • 使用异常处理的方法(即try-catch或try-finally块)不是内联的
    • 代码大的方法(约32个IL字节,但我可能记错了)不是内联的
    • 带有循环的方法不是内联的(除非循环可以完全展开或消除)

    这些启发式算法都是抖动的实现细节,这意味着它们没有正式的文档记录,可能随时会发生更改

    话虽如此,以下是一些您可能会感兴趣的文章(尽管其中一些文章现在已经有点长了):

    可能的副本