我可以让 Visual Studio 停止任务代码中未处理的异常吗?

Posted

技术标签:

【中文标题】我可以让 Visual Studio 停止任务代码中未处理的异常吗?【英文标题】:Can I have Visual Studio stop on unhandled exceptions inside Task code? 【发布时间】:2012-01-26 10:15:16 【问题描述】:

Visual Studio 有一个特性可以让调试未处理的异常变得更加容易:它会在有问题的代码行停止并显示异常。

似乎Task 类的设计方式总是抑制此功能:它捕获每个异常,然后在任务被Waited 或完成时重新抛出不同的异常。

我知道我可以让它在第一次出现异常时停止,但这并不总是有帮助:假设许多相同类型的已处理异常发生在未处理异常之前。在这种情况下,除了实际导致问题的异常之外,VS 将在每​​个非问题异常上停止。

另一种选择更不可接受:只查看InnerException 的堆栈跟踪:这意味着虽然我知道哪一行导致了异常,但我无法访问它的任何本地状态,如果程序是实际上停在那里。

我能否以某种方式获得两全其美,使用Task 类,但不必忍受降级的异常调试功能集?


额外问题:这是否意味着 await 块内的空引用异常不会导致 Visual Studio 直接停在那里,而是完全停在其他地方?

【问题讨论】:

私有 Task.Execute() 方法包含 catch Everything 语句。之后的 HandleException 和 AddException。一切都是私有的和非虚拟的。 @HansPassant 如果您希望将其发布为答案(暗示这基本上是不可能的),我最终会在没有更好答案的情况下接受它。 【参考方案1】:

Task 类型确实将所有异常包装到 AggregateException 中。但是,如果您使用的是 async/await 功能,那么当您使用 awaitTask 时,内部异常将被解包并重新抛出,从而保留原始堆栈跟踪。

VS11 将有更好的async 调试支持,但我认为它不可能达到你所希望的那样。 Task 是关于并发和异步代码的,这就是为什么我认为这永远行不通。

考虑一下,例如,如果您有一个 Task 在一个线程池线程上运行,那么您将转到 await。您可以在 try 块中 await 它以捕获来自 Task... 的异常,或者您可以在 try 块之外使用 await 它,使 Task 的异常未处理.

该示例的要点是,当抛出异常时,调试器不知道异常是否会被处理。使用同步代码,一旦抛出异常,就会检查堆栈 - 如果它未处理,调试器就会知道它未处理并且可以立即采取特殊措施(甚至在堆栈未展开之前)。

所以,我认为不可能做你想做的事。不过,您可以非常接近 IntelliTrace(仅在 VS Ultimate 中)。

【讨论】:

我知道它被抓住是因为人们不知道是否有什么东西想要在任务之外查看它。但我不会说我想要的从根本上是不可能的。它只是没有实施。 Task 没有TaskCreationOption.LeaveExceptionsAlone 是没有理由的。 async 不会指定该选项来获得它想要的功能;我会指定它以获得我想要的功能。唉,这不是当前实现的一部分。

以上是关于我可以让 Visual Studio 停止任务代码中未处理的异常吗?的主要内容,如果未能解决你的问题,请参考以下文章

Visual Studio 分析:从代码开始/停止

如何让 Visual Studio 2013 不停止错误生成 (C++)

用户控件总是使 Visual Studio 崩溃

禁用 Visual Studio 代码样式建议

如何让 Visual Studio 在出现 1 个(或 n 个)错误后自动停止编译?

Visual Studio Code的用户代码段在最新更新后停止工作