【C# 异常处理】StackTrace 堆栈跟踪

作用

在使用.NET编写的代码在debug时很容易进行排查和定位问题,一旦项目上线并出现问题的话那么只能依靠系统日志来进行问题排查和定位,但当项目复杂时,即各种方法间相互调用将导致要获取具体的出错方法或调用者将是一件不那么容易的事(因为没有PDB文件) 还好.NET提供了一系列系统组件来帮助我们获取项目堆栈信息用于定位和排查,以下代码将返回出错 堆栈调用的各上一级方法,直到最终的调用者方法  

入栈的过程

【C# 异常处理】StackTrace 堆栈跟踪

 

栈是一个先进后出(FILO)的结构,在从图上很容易就明白了,堆栈帧的定义了,即main()方法在调用时需要在栈上保存的一些数据所对应的内存就是main的堆栈帧,同理methodA()方法对应的就是methodA的堆栈帧了。

 

使用StackFrame和StackTrace类 获取当前函数名,当前代码行,源代码文件

StackTrace st = new StackTrace(new StackFrame(true));只能获取本函数的堆栈信息,可以改用下面的方法获取程序的调用堆栈信息。

StackTrace st = new StackTrace(new StackFrame(1,true));只能获取调用本函数的函数的堆栈信息,可以改用下面的方法获取程序的调用堆栈信息。

StackTrace st = new StackTrace(true); 就可以获取程序的整个堆栈调用关系的列表信息

案例

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            //只能获取本函数的堆栈信息,可以改用下面的方法获取程序的调用堆栈信息。
            StackTrace st = new StackTrace(new StackFrame(true));
            Console.WriteLine(" Stack trace for current level: {0}", st.ToString());
            StackFrame sf = st.GetFrame(0);
            Console.WriteLine(" File: {0}", sf.GetFileName());
            Console.WriteLine(" Method: {0}", sf.GetMethod().Name);
            Console.WriteLine(" Line Number: {0}", sf.GetFileLineNumber());
            Console.WriteLine(" Column Number: {0}", sf.GetFileColumnNumber());
            Console.WriteLine("------------------------------------------------");
            SayHello();
        }

        static void SayHello()
        {
            //只能获取调用本函数的函数的堆栈信息,可以改用下面的方法获取程序的调用堆栈信息。
            StackFrame stackFrame = new StackTrace(new StackFrame(1,true)).GetFrame(0);
            Console.WriteLine("Hello~");
            Console.WriteLine(" Stack trace for current level: {0}", stackFrame.ToString());
            Console.WriteLine("File Name: {0}", stackFrame.GetFileName());
            Console.WriteLine("Method Name: {0}", stackFrame.GetMethod().Name);
            Console.WriteLine("Line Number: {0}", stackFrame.GetFileLineNumber());
            Console.WriteLine("Column Number: {0}", stackFrame.GetFileColumnNumber());
        }
    }
}

 

StackFrame   stackFrame = new StackFrame(1, true);中1的意思了,就是指在堆栈帧中跳过的帧数,没错!!因为StackFrame   stackFrame = new StackFrame(1, true);是在SayHello()方法中定义的所以,跳过1帧就跟踪到了调用main()的地方了

上一篇:使用字体库


下一篇:问题尚未解决,希望知道伙伴回复讨论:2022-1-13 spring boot测试类junit可以注入Service但是无法注入User