获取async方法中调用方法的类的类型

时间:2013-06-11 07:10:59

标签: c#

我使用自定义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

1 个答案:

答案 0 :(得分:0)

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

由于支持格式化的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;
    }