首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >C#重新抛出异常:如何在集成开发环境中获取异常堆栈?

C#重新抛出异常:如何在集成开发环境中获取异常堆栈?
EN

Stack Overflow用户
提问于 2010-12-04 09:11:31
回答 2查看 1.8K关注 0票数 17

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

考虑下面的代码:

代码语言:javascript
复制
   static void foo() {
        throw new Exception("boo!");
    }

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

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

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

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

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

我的问题是:考虑到我的代码使用了重新抛出,有人能建议一种方便的方法来导航与异常关联的调用堆栈吗?我使用的是Visual Studio 2010。

EN

回答 2

Stack Overflow用户

发布于 2010-12-04 09:17:13

不是说你应该重新抛出,而是here的一篇关于如何保留堆栈跟踪的博客文章,本质上可以归结为:

代码语言:javascript
复制
private static void PreserveStackTrace(Exception exception)
{
  MethodInfo preserveStackTrace = typeof(Exception).GetMethod("InternalPreserveStackTrace",
    BindingFlags.Instance | BindingFlags.NonPublic);
  preserveStackTrace.Invoke(exception, null);
}

...
catch (Exception ex)
{
  // do something
  // ...
  PreserveStackTrace(ex);
  throw;
}
票数 1
EN

Stack Overflow用户

发布于 2018-03-01 00:36:52

Mike Stall给出了你的问题的great and simple solution

使用[DebuggerNonUserCode]属性标记重新抛出异常的方法

IDE将认为这不是您的代码,并且不会在该位置中断调试器,而是进一步查看堆栈,显示下一次重新抛出或初始异常位置。

(如果下一次重新抛出也很烦人,也将其标记为[DebuggerNonUserCode],依此类推...)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4351333

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档