用于登录.NET的堆栈跟踪

TDa*_*ver 5 .net c# logging attributes inline

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

是否有一条经验法则是何时何地内联?虚方法,静态方法,基类方法是否有任何不同?我只需要担心内部装配内联吗?内部名称空间

Sas*_*ein 5

是的,有一些规则,但它们是JIT编译器使用的启发式方法,这些启发式方法可能会在瞬间发生变化.

  1. 无法内联虚拟方法.
  2. 另一方面,接口方法可能是内联的,尽管我不能100%确定这是否会使堆栈跟踪崩溃.
  3. 当然可以内联静态方法和非虚拟实例方法.
  4. 内联可能跨越名称空间(当然)和程序集(不那么明显),因为它发生在运行时,当JIT编译方法调用时.
  5. "重"方法不会被内联.这取决于"重"的定义,并且是JIT适用的启发式的一部分.

我所知道的一些"沉重"的启发式:

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