获取当前类和方法名是否会降低性能

本文关键字:是否 性能 方法 获取 | 更新日期: 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]提供了定义调用方成员的源代码文件的完整路径(对于调试/记录目的可能更好,因为您知道在哪里调查可能的错误或错误)。