获取当前类和方法名是否会降低性能
本文关键字:是否 性能 方法 获取 | 更新日期: 2023-09-27 18:09:52
我有一个日志类,它创建了一个log4net实例,我可以在代码中的任何地方调用它。我也有一个方法来找出类和调用者的方法名。下面是我的方法:
private static string CurrentMethod()
{
StackTrace stackTrace = new StackTrace();
MethodBase method = stackTrace.GetFrame(2).GetMethod();
string cn = method.ReflectedType.Name;
string mn = method.Name;
string output = "[" + cn + "." + mn + "]";
return output;
}
我找到了这些文章:link1, Link2, Link3, Link4和很多其他的,但没有一个讨论效率和性能。现在我有两个问题:我可以在一个大项目中使用这个方法(一秒钟大约有1000个请求)吗?我的意思是这对项目的效率和性能有多大影响?有没有更好的方法来写上面的方法?
这里也是我的日志类的一部分。我想它可以帮助:
public static class Tools_Log
{
private static ILog logger;
public static ILog GetLogger()
{
return logger ?? (logger = CreateLogger());
}
private static ILog CreateLogger()
{
//Some log4net initialization
return LogManager.GetLogger("WebService");
}
private static string CurrentMethod()
{
StackTrace stackTrace = new StackTrace();
MethodBase method = stackTrace.GetFrame(2).GetMethod();
string cn = method.ReflectedType.Name;
string mn = method.Name;
string output = "[" + cn + "." + mn + "]";
return output;
}
public static string MessageForLogFile(string message, string exeption, double time)
{
string currentMethod;
string executiontime;
string consumer;
string body;
string output;
currentMethod = CurrentMethod();
executiontime = ExecutionTime(time);
body = BodyForLog(message, exeption);
consumer = Consumer();
output = OutPut(currentMethod, executiontime, consumer, body);
return output;
}
}
我这样调用日志类:
Tools_Log.GetLogger().Info(Tools_Log.MessageForLogFile("some text", "some text", execution time));
谢谢。
是的,反思总是一个较慢的过程。如果需要方法的名称,可以很容易地使用CallerMemberNameAttribute获得它。添加一个默认值为空的字符串参数,并将该属性应用于它,编译器将为您发送名称。
另外,如果你正在寻找快速日志记录,看看ETW而不是Log4Net。
: https://msdn.microsoft.com/en-us/library/windows/desktop/bb968803 (v = vs.85) . aspx
And Here: http://blogs.msdn.com/b/vancem/archive/2012/07/09/logging-your-own-etw-events-in-c-system-diagnostics-tracing-eventsource.aspx
编辑:
至于你在评论中的问题,不幸的是,你不能得到方法的名称2级以上,至少,不是直接。CallerMemberName
基本上只是语法糖,它告诉编译器获取调用成员的名称,并将其放在参数中,因此它在单一级别上工作。但是,由于它依赖于默认参数来完成此操作,如果您手动发送参数,则CallerMemberName
功能不适用,因此您可以这样做:
public void UserMethod()
{
IntermediaryMethod();
}
public void IntermediaryMethod([CallerMemberName] caller = "")
{
LogMethod(caller)
}
public void LogMethod([CallerMemberName] caller = "")
{
// Log...
}
如果你自己传递一个值,它不会被覆盖,所以做这样的事情将允许你从两个级别获得调用者的名称,同时保留单个级别的功能。
必须测量性能,这是使用分析器完成的。
顺便说一句,也许你可以使用。net 4.5中引入的调用者信息属性,而不是使用StackTrace
类。虽然[CallerMemberName]
属性不提供类名,但[CallerFilePath]
提供了定义调用方成员的源代码文件的完整路径(对于调试/记录目的可能更好,因为您知道在哪里调查可能的错误或错误)。