在 c# 方法中获取堆栈跟踪

Nei*_*ir0 5 c# logging callstack

我想实现通用记录器,它可以帮助我查看方法的调用堆栈。

我知道 System.Diagnostic 有一些方法,但它们是在 .net 4.0 中引入的,恐怕它不适用于 xamarin 或 .net core 或类似的东西。所以我想要更通用的解决方案。

另一个问题是 async\await,它会带来一些混乱。

我通过在每个方法中传递附加参数来存储一些上下文并帮助我确定调用堆栈,但是这个解决方案有点复杂。

我也可以使用不安全代码读取线程堆栈内存并自己检查调用堆栈,但它不可靠。

还有其他解决方案吗?

Man*_*mer 5

你可以只使用Environment.StackTrace。这从一开始就是框架的一部分。

Environment.StackTrace将完整的堆栈跟踪(包括对Environment.StackTrance自身的调用)作为行分隔字符串返回。

像这样的东西:

在 System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)
在 System.Environment.get_StackTrace()
在 WpfApplication2.MainWindow.GetStack(Int32 removeLines)
在 WpfApplication2.MainWindow.Button_Click(Object sender, RoutedEventArgs e)
...
在 System. Threading.ThreadHelper.ThreadStart()

您需要做的就是拆分/解析/格式化它,无论您想用它做什么。

由于您将在自己的类中使用它,请记住删除最新的 X 行。

这段代码应该可以在任何地方工作,因为它是故意低级的。

private static string[] GetStack(int removeLines)
{
    string[] stack = Environment.StackTrace.Split(
        new string[] {Environment.NewLine},
        StringSplitOptions.RemoveEmptyEntries);

    if(stack.Length <= removeLines)
        return new string[0];

    string[] actualResult = new string[stack.Length - removeLines];
    for (int i = removeLines; i < stack.Length; i++)
        // Remove 6 characters (e.g. "  at ") from the beginning of the line
        // This might be different for other languages and platforms
        actualResult[i - removeLines] = stack[i].Substring(6);

    return actualResult;
}
Run Code Online (Sandbox Code Playgroud)