如何捕获堆栈跟踪?

4
有时我会创建一个Exception实例,但不会抛出它(例如直接将其传递给处理程序)。
OnException(new AuthorizationException());

如何使用当前位置初始化堆栈跟踪?

问题是如何将当前堆栈跟踪附加到异常而不抛出它。 - Poma
3个回答

4
您可以使用Environment.StackTrace属性或使用StackTrace类:
var stack = new StackTrace();
var data = stack.<whatever you need from it>

但我必须得说:你所做的事情在概念上非常糟糕。

2
那是因为我正在对一个设计不佳的库进行包装,以使其变得更加友好。 - Poma
3
好的回答。如果您能解释一下为什么您认为OP正在做的事情是“概念上非常糟糕”的话,那会更好。在不抛出异常的情况下创建一个异常是不寻常的,但在我看来并不是那么牵强附会。 - stakx - no longer contributing

3

实际上你在问两个不同的问题(一个在标题中,另一个在结尾处)。

"如何捕获堆栈跟踪?"

只需查询 静态 System.Environment.StackTrace 属性 或通过 new System.Diagnostics.StackTrace(); 即可。

读取此属性不需要构造异常对象,因此也许这就是您所需的全部内容。

"如何使用当前位置初始化 [异常对象的] 堆栈跟踪?"

直到您实际 throw 异常对象之前,异常对象的 StackTrace 属性 才会被初始化。

"堆栈跟踪是在抛出异常时创建的。这与 Java 不同,Java 中堆栈跟踪是在异常对象构造期间创建的[...]。"公共语言基础结构注释标准, 第18章,第301页。

由于它是只读属性,您无法自己初始化它 - 除非您派生自己的异常类:

// don't do that:
class ExceptionWithPresetStackTrace : System.Exception
{
    public ExceptionWithPresetStackTrace(string stackTrace)
    {
        this.stackTrace = stackTrace;
    }

    public override string StackTrace
    {
        get
        {
            return stackTrace;
        }
    }
    readonly string stackTrace;
}

结合第一个问题的答案,您可以这样做:
OnException(new ExceptionWithPresetStackTrace(System.Environment.StackTrace));

然而,这通常是一个不好的想法,因为它使得可以创建异常对象,将开发人员指向任意随机位置(通过StackTrace属性),甚至是没有实际发生错误的位置。这是误导性的,应该避免。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接