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

时间:2021-12-02 09:05:31

I am trying to get the list of calls made from the beginning of a try block to the exception. In the code below, when I fall into the Catch block, the StackTrace in the Exception object is the following :

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

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

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

This is totally expected, but doesn't help me to get the history of calls. Does anybody have an idea on how I could do this?

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

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;
    }
}

I was surprised to see that the StackTrace property of the Exception object isn't StackTrace object. Is there any reason for this?

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

In the end, the purpose of all this is simple. If an exception is thrown during the execution of the code, I want to look at the meta data (attribute) of each of the methods called.

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

3 个解决方案

#1


As I understand your question, you want to be able to know which methods was called before MethodC in your try block. I don't think you can do that without adding code to your methods.

据我了解你的问题,你希望能够知道在try块中的MethodC之前调用了哪些方法。如果不向您的方法添加代码,我认为您无法做到这一点。

When MethodA finishes executing, it is no longer on the stack, so there is nowhere you can get the information from. Same goes for MethodB, and only MethodC is on the stack when the Exception occurs.

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

#2


It seems you're not going to be able to get a stack trace for each method called with the try block unless you add custom logging code to each method. However, you can create a System.Diagnostics.StackTrace option easily from an exception simply by passing the Exception object to the constructor. This will make available all the information about the stack trace including whether the exception was thrown from MethodA/MethodB/MethodC, which might be at least somewhat helpful to you.

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

Example code:

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());
        }
    }
}

(You can see this SO thread for the original answer containing the code. I've just slightly modified it.)

(您可以在包含代码的原始答​​案中看到此SO线程。我只是略微修改了它。)

Hope that's at least a partial solution to your question.

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

#3


You can easily get a StackTrace object from anywhere in your code but as has already been pointed out you can not get the full history of method calls.

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

#1


As I understand your question, you want to be able to know which methods was called before MethodC in your try block. I don't think you can do that without adding code to your methods.

据我了解你的问题,你希望能够知道在try块中的MethodC之前调用了哪些方法。如果不向您的方法添加代码,我认为您无法做到这一点。

When MethodA finishes executing, it is no longer on the stack, so there is nowhere you can get the information from. Same goes for MethodB, and only MethodC is on the stack when the Exception occurs.

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

#2


It seems you're not going to be able to get a stack trace for each method called with the try block unless you add custom logging code to each method. However, you can create a System.Diagnostics.StackTrace option easily from an exception simply by passing the Exception object to the constructor. This will make available all the information about the stack trace including whether the exception was thrown from MethodA/MethodB/MethodC, which might be at least somewhat helpful to you.

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

Example code:

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());
        }
    }
}

(You can see this SO thread for the original answer containing the code. I've just slightly modified it.)

(您可以在包含代码的原始答​​案中看到此SO线程。我只是略微修改了它。)

Hope that's at least a partial solution to your question.

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

#3


You can easily get a StackTrace object from anywhere in your code but as has already been pointed out you can not get the full history of method calls.

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