【发布时间】:2010-12-15 15:55:44
【问题描述】:
为什么堆栈的高位部分(在 Exception.StackTrace 中)被截断? 我们来看一个简单的例子:
public void ExternalMethod()
{
InternalMethod();
}
public void InternalMethod()
{
try
{
throw new Exception();
}
catch(Exception ex)
{
// ex.StackTrace here doesn't contain ExternalMethod()!
}
}
这似乎是“设计使然”。但是这种奇怪的设计的原因是什么?它只会让调试变得更加复杂,因为在日志消息中我无法理解是谁调用了 InternalMethod(),而且这些信息通常是非常必要的。
至于解决方案(对于那些不知道的人),据我了解有两种通用解决方案:
1) 我们可以记录静态的 Environment.StackTrace 属性,该属性包含整个堆栈(例如,从最上层(消息队列)开始,到发生异常的最深方法结束)。
2) 我们必须在最高级别捕获和记录异常。当我们需要在较低级别捕获异常以执行某项操作时,我们需要将其重新抛出(在 C# 中使用“throw”语句)。
但问题是关于这种设计的原因。
【问题讨论】:
-
一个对象为什么要关心谁调用了它?您的观点 (2),应该重新抛出异常,是正确的方法。
-
主要堆栈跟踪信息包含在异常中,用于调试目的。对于现有的设计,它对调试的帮助并不像如果它也有更高的堆栈部分一样。因为,我再说一遍,知道谁调用了该方法对于调试非常有用。
标签: c# .net exception architecture frameworks