【问题标题】:How to capture stack trace?如何捕获堆栈跟踪?
【发布时间】:2012-03-02 22:52:13
【问题描述】:

有时我会创建一个 Exception 实例而不抛出它(例如将其直接传递给处理程序)。

OnException(new AuthorizationException());

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

【问题讨论】:

标签: c# .net exception exception-handling


【解决方案1】:

您可以使用Environment.StackTrace 属性或使用StackTrace 类:

var stack = new StackTrace();
var data = stack.<whatever you need from it>

但我只需要补充一点:从概念上讲,您所做的事情非常糟糕。

【讨论】:

  • 嗯,那是因为我正在对设计不佳的库进行包装以使其更好一点
  • 好答案。如果您解释 为什么 您认为 “在概念上非常糟糕” OP 正在做什么,那就更好了。创建一个异常而不抛出它是不寻常的,但不是牵强的恕我直言。
【解决方案2】:

您实际上是在问两个不同的问题(一个在标题中,另一个在末尾)。

“如何捕获堆栈跟踪?”

只需查询static System.Environment.StackTrace property 或通过new System.Diagnostics.StackTrace();

读取这个属性根本不需要你构造一个异常对象,所以也许它就是你所需要的。

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

直到您实际throw 异常对象时,异常对象的StackTrace property 才会初始化。

“堆栈跟踪是在抛出异常时创建的。这与 Java 形成对比,Java 堆栈跟踪是在构造异常对象期间创建的 […]。”The Common Language Infrastructure Annotated Standard,频道。 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 属性),即使是实际上没有发生错误的位置。这是误导性的,应该避免。

【讨论】:

    【解决方案3】:

    您可以将当前堆栈跟踪作为字符串获取:

    http://msdn.microsoft.com/en-us/library/system.environment.stacktrace.aspx

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多