本文介绍了为什么堆在Exception.StackTrace被截断?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么堆栈(在Exception.StackTrace)的高位部分被截断?让我们来看看一个简单的例子:

Why does the high part of the stack (in Exception.StackTrace) gets truncated?Let's see a simple example:

public void ExternalMethod()
{
  InternalMethod();
}

public void InternalMethod()
{
  try
  {
    throw new Exception();
  }
  catch(Exception ex)
  {
    // ex.StackTrace here doesn't contain ExternalMethod()!
  }
}

看起来这是设计。但是,是什么原因这样一个奇怪的设计?它只会让调试更加复杂,因为在日志消息我不明白谁叫InternalMethod(),往往这些信息是非常必要的。

It seems like this is "by design". But what are the reasons for such a strange design? It only makes debugging more complex, because in log messages I can't understand who called InternalMethod() and often this information is very necessary.

至于解决方案(对于那些谁不知道),有2个通用的解决方案,因为我明白:
1)我们可以记录静态Environment.StackTrace属性,它包含了整个堆栈(例如,起始于hiest级别(消息队列),并在发生异常最深法)结束。
2)我们必须赶上并登录最高级别的例外。当我们需要捉对下级例外做一些事情,我们需要重新抛出(用扔在C#语句)进一步上升。

As for solutions (for those who don't know), there are 2 general solutions as I understand:
1) We can log static Environment.StackTrace property, which contains the whole stack (for example, starting at the hiest level (message queue) and ending at the deepest method in which exception occurs).
2) We have to catch and log exceptions on highest levels. When we need to catch exceptions on lower levels to do something, we need to rethrow (with "throw" statement in C#) it further up.

但问题是,对这种设计的原因。

But the question is about reasons of such design.

推荐答案

好了,现在我看到你得到什么的......对不起,我困惑的内联的事情。

Ok, now I see what your getting at... Sorry for my confusion on the inlining thing.

在捕获异常的堆栈是当前执行catch块,其中的异常被抛出只是一个增量。从概念上讲这种行为是在正确的Exception.StackTrack告诉您这个try / catch块的背景下发生异常。这使得异常堆栈跨虚拟呼叫转发,仍然保持精度。这个正在做的一个典型的例子是.NET远程异常。

The 'stack' in a caught exception is only a delta from the currently executing catch block to where the exception was thrown. Conceptually this behavior is correct in that the Exception.StackTrack tells you where the exception occurred within the context of this try/catch block. This allows exception stacks to be forwarded across 'virtual' calls and still maintain accuracy. One classic example of this being done is .Net Remoting exceptions.

因此​​,如果你想在catch块一个完整的堆栈报告,您将添加当前堆栈异常的堆栈,如下面的例子。唯一的问题是这可以是更昂贵的。

Thus if you want a complete stack report in the catch block you would add the current stack to the exception's stack as in the example below. The only problem is this can be more expensive.

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

这篇关于为什么堆在Exception.StackTrace被截断?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-31 12:05