.NET使用StackTrace獲取方法調用資訊

前言

在日常工作中,偶爾需要調查一些詭異的問題,而業務程式碼經過長時間的演化,很可能已經變得錯綜複雜,流程、分支眾多,如果能在關鍵方法的日誌里添加上調用者的資訊,將對定位問題非常有幫助。

介紹

StackTrace, 位於 System.Diagnostics 命名空間下,名字很直觀,它代表一個方法調用的跟蹤堆棧,裡面存放著按順序排列的棧幀對象(StackFrame),每當發生一次調用,就會壓入一個棧幀;而一個棧幀,則擁有本次調用的各種資訊,除了MethodBase,還包括所在的文件名、行、列等。

演示

下面程式碼演示了如何獲取調用者的方法名、所在文件、行號、列號等資訊。

public static string GetCaller()
{
       StackTrace st = new StackTrace(skipFrames: 1, fNeedFileInfo: true);
       StackFrame[] sfArray = st.GetFrames();

       return string.Join(" -> ",
            sfArray.Select(r =>
                $"{r.GetMethod().Name} in {r.GetFileName()} line:{r.GetFileLineNumber()} column:{r.GetFileColumnNumber()}"));
    
}

第一幀是 GetCaller本身,所以跳過;fNeedFileInfo設置成 true,否則調用者所在文件等資訊會為空。
簡單創建個控制台程式並添加幾個類模擬一下,輸出如下:

UpdateOrder in G:\examples\MethodCall2\ClassLevel6.cs line:11 column:8 -> 
Level5Method in G:\examples\MethodCall2\ClassLevel5.cs line:8 column:9 -> 
Level4Method in G:\examples\MethodCall2\ClassLevel4.cs line:10 column:9 -> 
Level3Method in G:\examples\MethodCall2\ClassLevel3.cs line:10 column:9 -> 
Level2Method in G:\examples\MethodCall2\ClassLevel2.cs line:10 column:9 -> 
InternalMethod in G:\examples\MethodCall2\ClassLevel1.cs line:12 column:13 -> 
Main in G:\examples\MethodCall2\Program.cs line:18 column:17

可以看到因為StackTrace是個棧結構(FILO),所以列印出來的順序也是由近及遠的。

鏈接