2

我使用自定义LogManager类来管理我的应用程序中的所有日志。我有一个如下所述的函数,它可以找到调用该方法的类,以便我可以轻松检测日志的来源。

然而,最近async在我的应用程序中实现了一些方法之后,我遇到了一个问题,即我似乎无法从async使用此函数的任何方法中找到调用类。(我好像只能得到调用方法)

我还尝试在日志参数中包含一个对象,并引用this,然后以这种方式获取对象的类型,但是我有很多静态方法,这对他们不起作用。我也不想每次我想记录一些东西时都这样做..

有没有人有更好的解决方案来查找从哪里调用异步方法的类?


我当前查找调用位置的功能:

    private string GetLocation()
    {
        string location = "Unknown";
        StackTrace stackTrace = new StackTrace();

        for (int i = 0; i < stackTrace.FrameCount; i++)
        {
            StackFrame stackFrame = stackTrace.GetFrame(i);
            string foundLocation = stackFrame.GetMethod().DeclaringType.Name;

            if (!foundLocation.Contains("Log"))
            {
                location = foundLocation;
                break;
            }
        }

        // Detects if log is comming from async method, detects method instead of classtype however
        if (location.StartsWith("<"))
        {
            string[] temp = location.Split('>');
            location = temp[0].Replace("<", "");
        }

        return location;
    }

当前日志方法:

    #region Log Method

    public static async void Log(LogLevel logLevel, string message, [CallerMemberName]string location = "")
    {
        LogMessage logMessage = new LogMessage(logLevel, message, location);
        await AddLogToCollection(logMessage);
    }

    #region Aditional log methods

    // Log With Formating -> doesn't work, cannot add the CallerMemberName after a range of params..
    public static void Log(LogLevel logLevel, string message, params object[] args, [CallerMemberName]string location = "")
    {
        string formatString = String.Format(message, args);
        Log(logLevel, formatString, location);
    }

    #endregion

    #endregion
4

1 回答 1

0

感谢 JonSkeet 的评论,对我处理日志的方式和我在本文中找到的信息进行了一些更改,我能够解决我的问题!

由于我Log支持格式化的方法具有对象参数的重载,因此我无法以这种方式传递CallerMemberName/ CallerFilePath。我通过使Log方法要求LogMessage直接传递(并在那里处理格式化)以及在该方法中添加的方法和类来解决这个问题。

非常感谢 JonSkeet 为我指明了正确的方向!


日志方法:

    public static async void Log(LogMessage logMessage, [CallerMemberName]string method = "", [CallerFilePath]string path = "")
    {
        logMessage.SetCaller(method, path);
        await AddLogToCollection(logMessage);
    }

SetCaller 方法:

    public void SetCaller(string method, string path)
    {
        string location = path;

        if (location.Contains("\\"))
        {
            string[] temp = location.Split('\\');
            location = temp[temp.Length - 1].Replace(".cs", "");
        }

        Method = method;
        Location = location;
    }
于 2013-06-11T08:56:49.400 回答