如何获取方法调用历史记录?

时间:2009-04-07 16:57:10

标签: c# .net exception exception-handling

我正在尝试从try块的开头到异常获取调用列表。在下面的代码中,当我进入Catch块时,Exception对象中的StackTrace如下:

  

在ConsoleApplication.Program.MethodC()/ at   ConsoleApplication.Program.Main(String [] args)。

这完全是预期的,但不能帮助我了解电话的历史。有没有人知道如何做到这一点?

static void MethodA() { }
static void MethodB() { }
static void MethodC() { throw new Exception(); }

static void Main(string[] args)
{
    try
    {
        MethodA();
        MethodB();
        MethodC();
    }
    catch (Exception e)
    {
        // Get list of calls
        throw;
    }
}

我很惊讶地发现Exception对象的StackTrace属性不是StackTrace对象。这有什么理由吗?

最后,所有这一切的目的都很简单。如果在执行代码期间抛出异常,我想查看每个被调用方法的元数据(属性)。

3 个答案:

答案 0 :(得分:1)

据我了解你的问题,你希望能够在try块中知道哪些方法在 MethodC之前被称为。如果不在方法中添加代码,我认为你不能这样做。

当MethodA完成执行时,它不再在堆栈中,因此无处可以从中获取信息。对于MethodB也是如此,当Exception发生时,只有MethodC在堆栈上。

答案 1 :(得分:0)

除非您为每个方法添加自定义日志记录代码,否则您似乎无法为使用try块调用的每个方法获取堆栈跟踪。但是,只需将System.Diagnostics.StackTrace对象传递给构造函数,即可轻松地从异常中创建Exception选项。这将提供有关堆栈跟踪的所有信息,包括是否从MethodA / MethodB / MethodC抛出异常,这可能至少对您有所帮助。

示例代码:

static void MethodA() { }
static void MethodB() { }
static void MethodC() { throw new Exception(); }

static void Main(string[] args)
{
    try
    {
        MethodA();
        MethodB();
        MethodC();
    }
    catch (Exception e)
    {
        System.Diagnostics.StackTrace callStack = new System.Diagnostics.StackTrace(e);
        System.Diagnostics.StackFrame frame = null;
        System.Reflection.MethodBase calledMethod = null;
        System.Reflection.ParameterInfo[] passedParams = null;
        for (int x = 0; x < callStack.FrameCount; x++)
        {
            callStack.GetFrame(x);
            calledMethod = frame.GetMethod();
            passedParams = calledMethod.GetParameters();
            foreach (System.Reflection.ParameterInfo param in passedParams)
                System.Console.WriteLine(param.ToString());
        }
    }
}

(对于包含代码的原始答​​案,您可以看到this SO thread。我只是略微修改了它。)

希望这至少是你问题的部分解决方案。

答案 2 :(得分:0)

您可以从代码中的任何位置轻松获取StackTrace对象,但正如已经指出的那样,您无法获得方法调用的完整历史记录。