nig*_*der 12 .net c# architecture frameworks exception
为什么堆栈的高位(在Exception.StackTrace中)会被截断?让我们看一个简单的例子:
public void ExternalMethod()
{
InternalMethod();
}
public void InternalMethod()
{
try
{
throw new Exception();
}
catch(Exception ex)
{
// ex.StackTrace here doesn't contain ExternalMethod()!
}
}
Run Code Online (Sandbox Code Playgroud)
看起来这是"按设计".但这种奇怪设计的原因是什么?它只会使调试变得更复杂,因为在日志消息中我无法理解谁调用了InternalMethod(),而且这些信息通常非常必要.
至于解决方案(对于那些不知道的人),我理解有两种通用解决方案:
1)我们可以记录静态Environment.StackTrace属性,它包含整个堆栈(例如,从hiest级别开始(消息队列) )并以发生异常的最深层方法结束).
2)我们必须捕获并记录最高级别的异常.当我们需要捕获较低级别的异常来做某事时,我们需要重新抛出(在C#中使用"throw"语句)它会进一步提升.
但问题是关于这种设计的原因.
csh*_*net 11
好的,现在我看到你得到了什么...抱歉我对内联的东西感到困惑.
捕获异常中的"堆栈"仅是从当前正在执行的catch块到抛出异常的位置的增量.从概念上讲,这种行为是正确的,因为Exception.StackTrack会告诉您在此try/catch块的上下文中发生异常的位置.这允许异常堆栈在"虚拟"调用之间转发,并仍然保持准确性.这样做的一个典型例子是.Net Remoting异常.
因此,如果您想在catch块中获得完整的堆栈报告,则可以将当前堆栈添加到异常堆栈中,如下例所示.唯一的问题是这可能更贵.
private void InternalMethod()
{
try
{
ThrowSomething();
}
catch (Exception ex)
{
StackTrace currentStack = new StackTrace(1, true);
StackTrace exceptionStack = new StackTrace(ex, true);
string fullStackMessage = exceptionStack.ToString() + currentStack.ToString();
}
}
Run Code Online (Sandbox Code Playgroud)
我知道在 catch 块中,如果您throw ex;这样做,它会截断此时的堆栈跟踪。throw 可能是“设计使然”的,因为它throw;不会在 catch 中截断堆栈。因为您抛出了一个新的异常,所以这里可能会发生同样的情况。
如果您导致实际异常(即int i = 100/0;),会发生什么?堆栈跟踪仍然被截断吗?
| 归档时间: |
|
| 查看次数: |
2428 次 |
| 最近记录: |