C#重新抛出异常:如何在IDE中获取异常堆栈?

red*_*una 17 .net c# exception visual-studio

之前有关于重新抛出异常的正确方法的讨论.相反,这个问题是关于如何在使用rethrow时从Visual Studio获得有用的行为.

考虑以下代码:

   static void foo() {
        throw new Exception("boo!");
    }

    static void Main(string[] args) {
        try {
            foo();
        } catch (Exception x) {
            // do some stuff
            throw;
        }
    }
Run Code Online (Sandbox Code Playgroud)

出现的异常具有正确的堆栈跟踪,显示foo()作为异常的来源.但是,GUI调用堆栈窗口只显示Main,而我期望它显示异常的调用堆栈,一直到foo.

当没有重新抛出时,我可以使用GUI快速导航调用堆栈,以查看导致异常的调用以及我们如何到达那里.

通过重新抛出,我希望能够做同样的事情.相反,GUI显示的调用堆栈对我没用.我必须将异常详细信息复制到剪贴板,将其粘贴到记事本,然后手动导航到我感兴趣的调用堆栈的任何功能.

顺便说一句,如果我添加[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]或者如果我将catch更改为just ,我会得到相同的行为catch (Exception).

我的问题是:鉴于我使用的代码重新抛出,有人可以建议一种方便的方法来导航与异常相关的调用堆栈吗?我正在使用Visual Studio 2010.

Chr*_*ich 11

调试器在throwin 处中断,Main因为该异常未处理.默认情况下,调试器只会中断未处理的异常.一旦停止Main,原始异常的调用堆栈将foo出现在异常中,但所有其他上下文都已丢失(例如本地,堆栈/内存状态).

这听起来像你想的调试器上打破throwfoo,所以你应该告诉调试器在第一次机会异常突破:

  1. 调试»异常......(Ctrl+ Alt+ E)
  2. 检查"Thrown"以查找您关心的异常类型(在本例中为Commange Language Runtime Exceptions)
  3. 单击确定
  4. 开始调试

在这种情况下,foo抛出异常时调试器会立即中断.现在,您可以在原始异常的上下文中检查堆栈,本地等.如果继续执行(F5),调试器将在重新抛出时再次中断Main.

采用另一种方法,如果您正在运行VS2010 Ultimate,您还可以使用IntelliTrace"向后调试"以查看异常时的参数,线程和变量.有关详细信息,请参阅此MSDN文章.(完全披露:我在与IntelliTrace密切相关的团队工作).

  • IntelliTrace看起来非常令人印象深刻!看起来这是我们用我在这里的工具最接近我们的目标,所以我接受你的答案(即使Athari的回答可能对其他人更好). (2认同)

Ath*_*ari 8

如果使用ReSharper,则可以将异常堆栈跟踪复制到剪贴板,然后在菜单中选择:ReSharper>工具>浏览堆栈跟踪(Ctrl + E,T).它将显示具有可点击位置的堆栈跟踪,因此您将能够快速导航.

http://www.jetbrains.com/resharper/webhelp/images/Reference__Windows__Stack_Trace_Explorer.png

在挖掘用户的日志时(如果记录了异常堆栈跟踪),此功能也非常有用.

  • @redtuna ReSharper是C#开发人员必备的.它可以多次加速很多任务. (2认同)