记录类和方法名称的最高效方法是什么?

9 .net c# reflection logging

我基本上想编写一个客户记录器/跟踪器,它还记录调用记录器/跟踪器的方法的类和方法名称.这应该是快速的,这样它不会影响应用程序的性能,强类型和清洁.有没有人有好主意?

以下是我所拥有的一些,但我担心由于反射导致的性能:

  • StackTrace/StackFrame(开销太大了?)

  • MethodInfo.GetCurrentMethod()(还是太慢了?还不是很干净)

  • 传递方法作为委托(C#可以隐式执行,我可以访问MethodInfo,但不是很干净)

我感谢任何人的评论.

更新:

我喜欢StackFrame的无尘,所以我在这里问了一个更具体的问题,关于StackFrame的性能,我得到了一些非常好的响应,包括性能测试.事实证明这MethodInfo.GetCurrentMethod()是最快的(在我的计算机上大约需要1微秒)并且new StackFrame(1)可以按需请求(在我的计算机上大约需要15-20微秒).我把方法作为委托选项抛出,因为当方法有多个参数时它太乱了.

结论:

我已经查看了所有选项,最好的是为PostSharp编写一个自定义插件,在编译期间在应用自定义属性时将方法名称作为字符串注入到MSIL中[Trace].在我看来,这是最快,最易维护的选择.这甚至可以实现更多的事情,比如传递参数名称和参数而不需要任何反射,并自动捕获和记录异常.这是我的相关问题以获取更多信息.

Ser*_*kov 5

最快的方法是在编译时执行此操作,这是真的,但在 .NET 中执行此操作最方便的方法是使用CallerMemberNameCallerFilePath和 .NET 4.5 中引入的其他编译器服务属性:

public void TraceMethodCall([CallerMemberName]string methodName)
{
}
Run Code Online (Sandbox Code Playgroud)


STW*_*STW 3

简而言之,最快的方法是在编译时静态地执行:

public void DoSomething()
{
    TraceCall("DoSomething");
} 

public void TraceCall(string methodName)
{
    if (!tracingEnabled) { return; }
    // Log the call
}
Run Code Online (Sandbox Code Playgroud)

那么这个问题本质上与你之前的问题相同;以可维护且准确的方式做到这一点的最佳方法是什么?我们之前讨论的运行时选项会对性能造成相对严重的影响,但代价是它们可以轻松实现。

正如在上一篇文章中提到的,这开始倾向于面向方面的编程;PostSharp 就是这样一个库,它可以帮助找到静态编译性能与简单维护之间的平衡。