C#获取当前堆栈的各调用方法列表

在使用.NET编写的代码在debug时很容易进行排查和定位问题,一旦项目上线并出现问题的话那么只能依靠系统日志来进行问题排查和定位,但当项目复杂时,即各种方法间相互调用将导致要获取具体的出错方法或调用者将是一件不那么容易的事(因为没有PDB文件)

还好.NET提供了一系列系统组件来帮助我们获取项目堆栈信息用于定位和排查,以下代码将返回出错堆栈调用的各上一级方法,直到最终的调用者方法

/******************************************************************
 * 创建人:HTL
 * 创建时间:2015-06-03 19:54:49
 * 说明: 获取出错时的堆栈调用方法列表
 * [email protected]
 *******************************************************************/
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:       [email protected]
    /// @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(‘-‘,‘>‘);
    }
}

执行以上代码效果(跟代码中的调用方法一致):

参考:

在线代码:http://ideone.com/34Q3Sk

博客园:

如何处理Windows Forms程序中未处理的异常

微软真是个十足的混蛋啊!让我们跟踪Exception到行把!(不明真相群众请入)

挖一挖C#中那些我们不常用的东西之系列(3)——StackTrace,Trim

浅析StackTrace

MSDN StackTrace 类

来自为知笔记(Wiz)

时间: 2024-09-30 19:41:43

C#获取当前堆栈的各调用方法列表的相关文章

JavaScript获取后台C#变量以及调用后台方法 &amp;&amp; 获取请求的URL参数

一.当然我们可以在后台中获取参数的值,然后在前台js代码中获取变量的值,具体做法请参考下面JavaScript获取后台C#变量以及调用后台方法. 其实我们也可以直接在js中获取请求的参数的值,通过使用window.location.search可以获取到当前URL的?号开始的字符串,如前面的链接获取到的search为?id=001.再对获取的字符串进行处理,就可以获取到参数的值了. 复制代码 代码如下: 1 function getUrlParam(name) { 2 var reg = new

通过反射获取及调用方法(Method)

1.获取方法使用反射获取某一个类中的方法,步骤:①找到获取方法所在类的字节码对象②找到需要被获取的方法 Class类中常用方法: public Method[] getMethods():获取包括自身和继承过来的所有的public方法 public Method[] getDeclaredMethods():获取自身所有的方法(不包括继承的,和访问权限无关) public Method getMethod(String methodName,Class<?>...parameterTypes)

关于页面刷新或者调用方法事获取不到元素信息或者出现缺少对象错误的换位思考setTimeout的使用

这两天客户的需求不能定下来,做闲人好长时间了,不如来整理下最近碰到的一些个小麻烦. 正题: 场景一. 最近在开发的过程中使用到了百度的富客户端文本编辑器(ueditor)---这是一款功能很强大的文本编辑器, 现在需求:当在这个页面打开以后需要把用户上次编辑的信息写回到此文本编辑器中去,这里使用的方法是ueditor给定的方法.同时使用iframe对此编辑器进行了页面嵌套的显示. 1 //将html代码展示到编辑器中. 2 function insertHtml(value) { 3 setCo

原 .NET/C# 反射的的性能数据,以及高性能开发建议(反射获取 Attribute 和反射调用方法)

大家都说反射耗性能,但是到底有多耗性能,哪些反射方法更耗性能:这些问题却没有统一的描述. 本文将用数据说明反射各个方法和替代方法的性能差异,并提供一些反射代码的编写建议.为了解决反射的性能问题,你可以遵循本文采用的各种方案. 本文内容 反射各方法的性能数据 反射的高性能开发建议 创建类型的实例 反射获取 Attribute 反射调用公共 / 私有方法 使用预编译框架 附本文性能测试所用的代码 所有反射相关方法 IsDefined 和 GetCustomAttribute 的专项比较 参考资料 反

Delphi按名字调用方法高级解决方案

Delphi按名字调用方法高级解决方案 博客分类: 编程基础 DelphiJ#ASPDOS数据结构 按名字调用方法似乎一直以来都是大家比较关注的技术,在论坛上有一个经典的答复: type    TProcedure = procedure(Test: string) of object; procedure ExecuteRoutine(Obj: TObject; Name, Param: string);  var    PMethod: TMethod;    AProcedure: TPr

C#中dll调用方法

一.      DLL与应用程序 动态链接库(也称为DLL,即为“Dynamic Link Library”的缩写)是Microsoft Windows最重要的组成要素之一,打开Windows系统文件夹,你会发现文件夹中有很多DLL文件,Windows就是将一些主要的系统功能以DLL模块的形式实现. 动态链接库是不能直接执行的,也不能接收消息,它只是一个独立的文件,其中包含能被程序或其它DLL调用来完成一定操作的函数(方法.注:C#中一般称为“方法”),但这些函数不是执行程序本身的一部分,而是根

thinkphp获取特定字段的两种方法

thinkphp getField( )和field( ) 2014年10月05日 ⁄ 综合 ⁄ 共 1509字 ⁄ 字号 小 中 大 ⁄ 评论关闭 做数据库查询的时候,比较经常用到这两个,总是查手册,记不住,现在把它总结下,希望以后用的时候不查手册了. 不管是用select 查询数据集,还是用find 查询数据,常配合连贯操作where.field.order等一起使用.  field():用于定义要查询的字段(支持字段排除) 用法:field($field , $except=false)

spring aop 动态代理批量调用方法实例

今天项目经理发下任务,需要测试 20 个接口,看看推送和接收数据是否正常.因为对接传输的数据是 xml 格式的字符串,所以我拿现成的数据,先生成推送过去的数据并存储到文本,以便验证数据是否正确,这时候要批量调用这些同名方法,我觉得这里可以发展成有潜力的代码. 推送比较好做数据,队友们都写好代码,但是有个问题,方法要的值都大致相同,封装的方式不一致,多人开发,有的封装对象里面,有的直接使用 Map.get(),唉,一千个人一千个哈姆雷特嘛,只好利用反射和动态代理节省自己的代码量,而且这种方式练练手

Unity3d获取APK签名及公钥的方法

在Unity3d项目中获取APK包签名公钥的方法,核心思想就是通过JNI调用Android提供的方法.不过Unity3d提供了比JNI更上一层的类AndroidJavaObject以及继承它的AndroidJavaClass,帮助开发者省去很多工作.这两种类型的函数及内部原理可以看Unity3d官网,也可以反编译看里面的代码,直接说用法. 首先要获取到当前运行程序的Activity才好继续以后的操作.Unity3d在程序启动时记录下了这个值,可以通过UnityPlayer类的静态字段curren