加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 显示重新抛出的异常堆栈跟踪,而不是从抛出点堆栈跟踪

发布时间:2020-12-15 23:53:01 所属栏目:百科 来源:网络整理
导读:我已经在VS2005中确认了同样的行为,所以我把它称为.NET(1.1)错误是错误的. 我将在下面留下原始问题,但我修改过的问题是这样的:我如何让Visual Studio为我提供我已捕获并在“调用堆栈”窗口中重新抛出的异常的堆栈跟踪,而不是仅显示从throw语句的角度调用堆
我已经在VS2005中确认了同样的行为,所以我把它称为.NET(1.1)错误是错误的.

我将在下面留下原始问题,但我修改过的问题是这样的:我如何让Visual Studio为我提供我已捕获并在“调用堆栈”窗口中重新抛出的异常的堆栈跟踪,而不是仅显示从throw语句的角度调用堆栈?

情况是我在运行时决定全局异常处理程序是打开还是关闭 – 如果它关闭,我希望VS捕获异常,这样我就可以通过调用堆栈来找出出错的地方.

以前,全局异常处理程序是否已编译到程序中.但是情况已经发生了变化,现在我们需要在运行时做出决定 – 看起来我可能需要回到宏观方式来做,但没有宏:

if (allow_bubble_up)
{
    Foo();
}
else
{
    try
    {
        Foo();
    }
    catch (Exception e)
    {
       GlobalExceptionHandler(e);
    }
}

但对我来说,这种做法对DRY非常不利.

显然,.NET 1.1中存在一个错误,如果你有一个空的throw语句来重新抛出一个捕获的异常,那么堆栈跟踪就会从发生抛出的地方开始,而不是重新抛出整个异常的堆栈跟踪 – – 至少,我在一些博客上看到它被称为bug,但我无法获得更多关于它的信息.

更具体一点,QuickWatch中$exception的StackTrace属性显示正确的数据,但VS中的Call Stack窗口仅将调用堆栈显示为throw语句的级别.

在这个示例代码中,我只能看到Main的1级深堆栈跟踪,即使我应该看到一些对Foo的几次调用的堆栈跟踪.

static public void Foo(int i)
{
    if (i > 4)
    {
        throw new ArgumentOutOfRangeException();
    }
    Foo(i + 1);
}

static void Main(string[] args)
{
    bool allow_bubble_up = true;
    try
    {
        Foo(0);
    }
    catch (Exception e)
    {
        if (allow_bubble_up)
        {
            // stack trace just shows Main
            throw;

            // also just shows Main
            //throw new Exception("asdf",e);

            // STILL just shows Main
            //throw e;
        }
        else
        {
            System.Console.WriteLine(e);
        }
    }
}

Fabrice Marguerie’s blog显示了如何解决.NET 2.0的某些类型的重新抛出的堆栈跟踪,并在底部他说要检查Chris Taylor的博客,了解如何在.NET 1.1中执行此操作.我不得不搜索到find it on archive.org.我认为我正确地实现了它,但我仍然在主要处有一个堆栈跟踪 – 他的解释并不十分清楚,我宁愿不要乱用代码库(换行)任何超出必要的功能的另一种方法中的现有功能集.

我可以在捕获和重新引发的异常的属性中看到正确的堆栈跟踪,但VS显示的可导航堆栈跟踪是无用的,因为它只跟踪throw语句.如果我从未捕获并重新抛出异常,我会获得完整且正确的堆栈跟踪.

如何在VS中显示正确的堆栈跟踪?
我希望有一些简单的解决方法,而且我一直在寻找错误的术语.

不幸的是,它必须是VS2003 C#.

如果不清楚,这里是截图(您可能需要右键单击并查看图像):

alt text http://img257.imageshack.us/img257/1124/40727627.png

解决方法

Visual Studio将显示停止位置的调用堆栈.

在未处理的异常的情况下,它将停止抛出该异常的位置.即你的“抛出”声明.但是,如果您的代码处理异常,那么Visual Studio会假设您知道您正在做什么,并忽略该异常.它只会在Main()中重新抛出时捕获异常,因为你没有在程序中处理它.

如果您想在visual studio中捕获原始异常,您有两种选择:

>不要在代码中捕获异常.默认情况下,Visual Studio仅在未处理的异常处停止.这当然意味着您的程序不会在运行时处理异常,所以这不是一个非常有用的方法!>使用您的代码捕获并重新抛出异常(正如您所做的那样),但将Visual Studio配置为在首次抛出内部异常时停止.转到Debug> Exceptions并勾选“公共语言运行时”例外框(停止任何异常)或浏览子树以启用异常捕获特定异常(提示:如果您知道异常名称,请单击Find …按钮并输入名称的一部分,例如“FileNotFound”,以快速找到异常).这将使VS停止在内部异常,并且如果您在检查异常详细信息后选择继续执行,则仅转到catch {}语句.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读