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

栈是一个先进后出(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); 就可以获取程序的整个堆栈调用关系的列表信息
堆栈的跟踪依依赖于.pdb文件。如果没有.pdb文件将无法输出源代码中的文件路径和行号、列号。
案例
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()的地方了
编程是个人爱好
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)