C#獲取當前堆棧的各調用方法列表

在使用.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('-','>');
    }
}

 

 
執行以上代碼效果(跟代碼中的調用方法一致):
 
 
參考:
 
博客園:
 
 



相關文章
相關標籤/搜索