System.Diagnostics.StackTrace 是 .NET 診斷、日誌、AOP 切面編程中的利器,能在執行時完整捕捉呼叫堆疊資訊。本文透過完整範例示範如何獲取方法名稱、呼叫層級、檔案行號等關鍵資訊,並探討實際應用場景。
new StackTrace(true) 參數 true 表示捕捉檔案資訊(需 PDB 符號檔)。GetMethod():取得 MethodBase,可進一步獲取 Name、DeclaringType、Module 等。GetFileName()、GetFileLineNumber()、GetFileColumnNumber():原始碼位置(需偵錯建置)。GetILOffset()、GetNativeOffset():IL/原生位移。using System;
using System.Diagnostics;
namespace StackTraceDemo
{
class Program
{
static void Main(string[] args)
{
A();
B();
Console.ReadKey();
}
static void A()
{
ShowStack();
}
static void B()
{
ShowStack();
A(); // 巢狀呼叫
}
static void ShowStack()
{
var st = new StackTrace(true); // true = capture file info
var frames = st.GetFrames();
Console.WriteLine("=== 完整呼叫堆疊 (由外而內) ===");
for (int i = frames.Length - 1; i >= 0; i--)
{
var method = frames[i].GetMethod();
var typeName = method.DeclaringType?.FullName ?? "";
Console.Write($"{typeName}.{method.Name} -> ");
}
Console.WriteLine("\n***********************\n");
// 進階:只取業務邏輯層(跳過框架內部幀)
Console.WriteLine("=== 過濾後的業務呼叫鏈 ===");
foreach (var frame in frames)
{
var method = frame.GetMethod();
if (method.DeclaringType?.Namespace?.StartsWith("StackTraceDemo") == true)
{
Console.WriteLine($"{method.DeclaringType.Name}.{method.Name} " +
$"(File: {frame.GetFileName()}, Line: {frame.GetFileLineNumber()})");
}
}
}
}
}
=== 完整呼叫堆疊 (由外而內) === StackTraceDemo.Program.Main -> StackTraceDemo.Program.A -> StackTraceDemo.Program.ShowStack -> *********************** === 完整呼叫堆疊 (由外而內) === StackTraceDemo.Program.Main -> StackTraceDemo.Program.B -> StackTraceDemo.Program.ShowStack -> *********************** === 完整呼叫堆疊 (由外而內) === StackTraceDemo.Program.Main -> StackTraceDemo.Program.B -> StackTraceDemo.Program.A -> StackTraceDemo.Program.ShowStack -> *********************** === 過濾後的業務呼叫鏈 === Program.A (File: Program.cs, Line: 22) Program.ShowStack (File: Program.cs, Line: 35)
Exception.StackTrace 之外的更多上下文(如參數值、區域變數配合 StackFrame.GetMethod().GetParameters())。StackTrace 建構較重(需走 Managed Stack Walk),避免在高頻熱路徑(如迴圈、底層庫)中頻繁建構。建議採樣或條件觸發。[MethodImpl(MethodImplOptions.NoInlining)]。SecurityPermission(UnmanagedCode)。System.Diagnostics.Activity / ActivitySource 進行分散式追蹤,開銷更低、功能更強。善用 StackTrace 能大幅提升診斷能力,但請謹記「按需採樣、避開熱路徑」的黃金法則。