【问题标题】:Is there a tidier way to get call stack information than Environment.StackTrace?有没有比 Environment.StackTrace 更简洁的方法来获取调用堆栈信息?
【发布时间】:2019-10-24 15:52:55
【问题描述】:

我想记录通过一些复杂的多线程代码传递的对象上的调用堆栈。 Environment.StackTrace 为您提供调用堆栈,但很难阅读。

at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)\r\n   at System.Environment.get_StackTrace()\r\n   at Foo.Bar.Biz(Monolith monolith) in C:\\Users\\Me\\Google\\Source\\Search.cs :line 70\r\n   at Blah.Nonsense.Business(Monolith monolith) in C:\\Users\\Me\\Google\\Source\\Prediction.cs :line 129\r\n   at ... you get the point

我只需要查看文件、类、方法和行。有没有正确的方法来获取这些信息?以下是我编写的方法,但由于所有字符串操作,它非常难看。

public static List<string[]> GetCallstack()
{
    List<string[]> callstack = new List<string[]>();

    string stackTrace = Environment.StackTrace;
    string[] stackInstances = stackTrace.Split(new string[] { "\r\n" }, StringSplitOptions.None);
    foreach (string stackInstance in stackInstances)
    {
        var stackInstanceComponents = stackInstance.Split(new string[] { ") in ", ":line " }, StringSplitOptions.None);
        if (stackInstanceComponents.Length == 3)
        {
            string classAndMethod = string.Join(".", stackInstanceComponents[0].Split('.').Reverse().Take(2).Reverse().ToArray()) + ")";
            string path = string.Join("/", stackInstanceComponents[1].Split(System.IO.Path.DirectorySeparatorChar).Reverse().Take(2).Reverse().ToArray()).Replace("at ", "");
            string line = stackInstanceComponents[2];

            if (classAndMethod != "Utility.GetCallstack()")
            {
                callstack.Add(new string[] { classAndMethod, path, line });
            }
        }
    }

    return callstack;
}

【问题讨论】:

标签: c# .net


【解决方案1】:

http://www.csharp-examples.net/reflection-callstack/

using System.Diagnostics;

[STAThread]
public static void Main()
{
  StackTrace stackTrace = new StackTrace();           // get call stack
  StackFrame[] stackFrames = stackTrace.GetFrames();  // get method calls (frames)

  // write call stack method names
  foreach (StackFrame stackFrame in stackFrames)
  {
    Console.WriteLine(stackFrame.GetMethod().Name);   // write method name
  }
}

使用StackTrace.GetFrames() 获取所有帧,然后每个StackFrame 具有all required methodsGetFileName()GetMethod()GetFileLineNumber() 以及您使用的类名GetMethod().DeclaringType...

【讨论】:

  • 仅供参考:OP 要求是 I just need to see the file, class, method, and line. 您的代码仅打印方法名称,因此没有文件或行。
  • @RandRandom 然后看看the documentation for StackFrame....它拥有一切...GetFileName(),GetFileLineNumber(),GetMethod()...
  • 我的意思是,你认为我是如何得到我正在使用的代码的?是的,我用谷歌搜索了它。
【解决方案2】:

您可以改用System.Diagnostics.StackTrace 类。它将为您提供堆栈跟踪的分层视图。查看this 以获取有关执行您想要的类和代码示例的完整详细信息。但是请注意,您还必须过滤掉您需要的内容。但是,StackTrace 允许您以更清洁的方式进行操作。另一种选择是使用StackFrame class,它提供了更细粒度的信息。这个类有GetFileName()GetMethod()GetFileLineNumber(),类名可以使用GetMethod().DeclaringType

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-17
    相关资源
    最近更新 更多