C# 有没有比Environment.StackTrace更整洁的方法来获取调用堆栈信息?

C# 有没有比Environment.StackTrace更整洁的方法来获取调用堆栈信息?,c#,.net,C#,.net,我想在通过一些复杂的多线程代码传递的对象上记录调用堆栈。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\\Searc

我想在通过一些复杂的多线程代码传递的对象上记录调用堆栈。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;
}

用于获取所有帧,然后每个帧都有:,对于类名,使用GetMethod.DeclaringType…

请参见


用于获取所有帧,然后每个帧都有:,对于类名,使用GetMethod.DeclaringType…

可以改用System.Diagnostics.StackTrace类。它将为您提供堆栈跟踪的分层视图。查看该类的完整详细信息,以及实现所需功能的代码示例。但是请注意,您还必须过滤掉您需要的内容。但是,StackTrace允许您以更干净的方式进行操作。另一种选择是使用提供更细粒度信息的。此类具有GetFileName、GetMethod、GetFileLineNumber,对于类名,可以使用GetMethod.DeclaringType

代替System.Diagnostics.StackTrace类。它将为您提供堆栈跟踪的分层视图。查看该类的完整详细信息,以及实现所需功能的代码示例。但是请注意,您还必须过滤掉您需要的内容。但是,StackTrace允许您以更干净的方式进行操作。另一种选择是使用提供更细粒度信息的。此类具有GetFileName、GetMethod、GetFileLineNumber,对于类名,您可以使用GetMethod。DeclaringType

MSDN的示例很少非常有用,但在这种情况下。MSDN的示例很少非常有用,但在这种情况下。仅供参考:OPs要求是我只需要查看文件、类、方法和行。您的代码只打印方法名,因此没有文件或行。@RandRandom然后查看。。。。它拥有一切。。。GetFileName,GetFileLineNumber,GetMethod…我的意思是,你认为我是如何得到我正在使用的代码的?是的,我在谷歌上搜索过。仅供参考:OPs要求是我只需要查看文件、类、方法和行。您的代码只打印方法名,因此没有文件或行。@RandRandom然后查看。。。。它拥有一切。。。GetFileName,GetFileLineNumber,GetMethod…我的意思是,你认为我是如何得到我正在使用的代码的?是的,我用谷歌搜索了一下。
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
  }
}