我基本上想编写一个客户记录器/跟踪器,它还记录调用记录器/跟踪器的方法的类和方法名称.这应该是快速的,这样它不会影响应用程序的性能,强类型和清洁.有没有人有好主意?
以下是我所拥有的一些,但我担心由于反射导致的性能:
StackTrace/StackFrame(开销太大了?)
MethodInfo.GetCurrentMethod()(还是太慢了?还不是很干净)
传递方法作为委托(C#可以隐式执行,我可以访问MethodInfo,但不是很干净)
我感谢任何人的评论.
更新:
我喜欢StackFrame的无尘,所以我在这里问了一个更具体的问题,关于StackFrame的性能,我得到了一些非常好的响应,包括性能测试.事实证明这MethodInfo.GetCurrentMethod()
是最快的(在我的计算机上大约需要1微秒)并且new StackFrame(1)
可以按需请求(在我的计算机上大约需要15-20微秒).我把方法作为委托选项抛出,因为当方法有多个参数时它太乱了.
结论:
我已经查看了所有选项,最好的是为PostSharp编写一个自定义插件,在编译期间在应用自定义属性时将方法名称作为字符串注入到MSIL中[Trace]
.在我看来,这是最快,最易维护的选择.这甚至可以实现更多的事情,比如传递参数名称和参数而不需要任何反射,并自动捕获和记录异常.这是我的相关问题以获取更多信息.
最快的方法是在编译时执行此操作,这是真的,但在 .NET 中执行此操作最方便的方法是使用CallerMemberName、CallerFilePath和 .NET 4.5 中引入的其他编译器服务属性:
public void TraceMethodCall([CallerMemberName]string methodName)
{
}
Run Code Online (Sandbox Code Playgroud)
简而言之,最快的方法是在编译时静态地执行:
public void DoSomething()
{
TraceCall("DoSomething");
}
public void TraceCall(string methodName)
{
if (!tracingEnabled) { return; }
// Log the call
}
Run Code Online (Sandbox Code Playgroud)
那么这个问题本质上与你之前的问题相同;以可维护且准确的方式做到这一点的最佳方法是什么?我们之前讨论的运行时选项会对性能造成相对严重的影响,但代价是它们可以轻松实现。
正如在上一篇文章中提到的,这开始倾向于面向方面的编程;PostSharp 就是这样一个库,它可以帮助找到静态编译性能与简单维护之间的平衡。