在使用.NET編寫的代碼在debug時很容易進行排查和定位問題,一旦項目上線並出現問題的話那么只能依靠系統日志來進行問題排查和定位,但當項目復雜時,即各種方法間相互調用將導致要獲取具體的出錯方法或調用者將是一件不那么容易的事(因為沒有PDB文件)
還好.NET提供了一系列系統組件來幫助我們獲取項目堆棧信息用於定位和排查,以下代碼將返回出錯
堆棧調用的各上一級方法,直到最終的調用者方法
/****************************************************************** * 創建人:HTL * 創建時間:2015-06-03 19:54:49 * 說明: 獲取出錯時的堆棧調用方法列表 * Huangyuan413026@163.com *******************************************************************/ using System; public class StackTraceTest { public static void Main() { m1(); } static void m1(){ m2(); } static void m2(){ m3(); } static void m3(){ ResponseWrite(); } static void ResponseWrite(){ ResponseWriteError(); } static void ResponseWriteError(){ //將錯誤信息寫入日志 Console.WriteLine(GetStackTraceModelName()); } /// <summary> /// @Author: HTL /// @Email: Huangyuan413026@163.com /// @DateTime: 2015-06-03 19:54:49 /// @Description: 獲取當前堆棧的上級調用方法列表,直到最終調用者,只會返回調用的各方法,而不會返回具體的出錯行數,可參考:微軟真是個十足的混蛋啊!讓我們跟蹤Exception到行把!(不明真相群眾請入) /// </summary> /// <returns></returns> static string GetStackTraceModelName() { //當前堆棧信息 System.Diagnostics.StackTrace st = new System.Diagnostics.StackTrace(); System.Diagnostics.StackFrame[] sfs = st.GetFrames(); //過慮的方法名稱,以下方法將不會出現在返回的方法調用列表中 string _filterdName = "ResponseWrite,ResponseWriteError,"; string _fullName = string.Empty, _methodName = string.Empty; for (int i = 1; i < sfs.Length; ++i) { //非用戶代碼,系統方法及后面的都是系統調用,不獲取用戶代碼調用結束 if (System.Diagnostics.StackFrame.OFFSET_UNKNOWN == sfs[i].GetILOffset()) break; _methodName = sfs[i].GetMethod().Name;//方法名稱 //sfs[i].GetFileLineNumber();//沒有PDB文件的情況下將始終返回0 if (_filterdName.Contains(_methodName)) continue; _fullName = _methodName + "()->" + _fullName; } st = null; sfs = null; _filterdName = _methodName = null; return _fullName.TrimEnd('-','>'); } }
執行以上代碼效果(跟代碼中的調用方法一致):

參考:
博客園: