Visual Studio 2015 中断未处理的异常不起作用
Posted
技术标签:
【中文标题】Visual Studio 2015 中断未处理的异常不起作用【英文标题】:Visual Studio 2015 break on unhandled exceptions not working 【发布时间】:2015-10-11 11:54:21 【问题描述】:Visual Studio 曾经有一个特定的复选框来“中断未处理的异常”。在 2015 年,这已被删除(或移动到我找不到的地方)。因此,如果我未能提供用户级异常处理程序,现在我转换的项目不再中断。我不想打破所有“抛出的异常”,因为我处理特定的异常。就在我未能提供特定处理程序的地方。
现在我的代码只是退出当前过程并在下一个调用堆栈位置继续执行,不好。
有谁知道如何在 Visual Studio 2015 中恢复它?我昨天刚升级到社区版。
【问题讨论】:
Visual Studio 2015 将保留您以前版本的当前布局,如果Tool
或 Window
选项卡没有所有所需的位置。在您的情况下,您正在寻找 Exception Settings.
@greg,我并不是不知道在哪里可以找到面板。我担心的是我正在寻找的行为不在该面板中。
这里有同样的问题。在我们的例子中,当 autofac 没有注册所有类型时,我们期望异常中断。使用与 vs2013 相同的解决方案它可以工作,在 vs2015 中我们什么也得不到。这也是其他第三方注册和异常(如nservicebus)的问题。我想知道它是否仅适用于在vs2013中创建并在vs2015中运行的项目
那个新的工具窗口真的很烂。
根据MS Classifications of Exceptions,如果您有 unhandled 异常,它总是会破坏调试器。可能您必须在“选项 -> 调试 -> 常规”列表中选中“当 excptions 跨 AppDomain 时中断 ...”选项。
【参考方案1】:
当您开始调试时,默认情况下,右下方窗格中会出现一个名为“异常设置”的新窗口。它拥有您所期望的所有选项。
您可以使用 CTRL+ALT+E
调出它这允许您挑选哪些异常会导致调试器中断。
不过,关键是您还可以设置这些异常是否总是中断,或者仅在它是未处理的异常时才中断——但这并不是很直观。
您需要先在“工具”>“选项”>“调试”下选中“仅启用我的代码”。
然后,您可以在新的“异常设置”窗口中右键单击列标题(抛出时中断),并添加“附加操作”列,然后您可以将每个异常设置为“用户未处理时继续”代码”。
因此,只需右键单击异常或整个组并禁用“在用户代码中未处理时继续”标志。不幸的是,“Additional Actions”列将显示为空,这与“Break when unhandled in user code”相同。
更多信息在这里:
http://blogs.msdn.com/b/visualstudioalm/archive/2015/02/23/the-new-exception-settings-window-in-visual-studio-2015.aspx
【讨论】:
实际上那个窗口只有“break with throw”的选项。那不是我想要的。我想要“在未处理时中断”。 这就是问题所在。它不会破裂。正如我上面所说,它退出(退出)当前过程调用并开始执行调用过程中的下一行代码。 我确实启用了“仅我的代码”。 @TomStudee 我也有同样的问题。我想要的是“未处理时中断”,但我得到的是“抛出时中断”。问题是:如何获得“未处理时中断”? @TomStudee 我刚刚添加了一些急需的说明,因为您缺少允许您将异常设置为仅在未处理时才中断的关键设置。【参考方案2】:对于只想在异常涉及其代码时中断的 googler,Visual Studio 2015 中有一个选项:选项->调试->常规->仅我的代码。一旦检查,当异常在你的代码之外被管理(抛出和捕获)时,它允许不中断。
【讨论】:
这让我避免了另一种情况,即 VS2015 出于某种原因拒绝输入某些代码。代码是“我的”,但有些东西触发了“只是我的代码”标志。我猜想在运行 2 个 VS 实例和一个独立的 Web 服务器时某个地方存在错误,可能还有更多。【参考方案3】:尝试按照说明操作:
-
在“异常设置”窗口中,右键单击窗口,然后选择“显示列”,打开上下文菜单。 (如果您关闭了 Just My Code,您将看不到此命令。)
您应该会看到名为 Additional Actions 的第二列。此列在特定异常上显示用户代码未处理时继续,这意味着如果该异常未在用户代码中处理但在外部代码中处理,调试器不会中断。
您可以为特定异常(选择异常、右键单击并选择/取消选择在用户代码中未处理时继续)或整个异常类别(例如,所有公共语言运行时异常)更改此设置)。
https://msdn.microsoft.com/en-us/library/x85tt0dd.aspx
【讨论】:
完全同意。默认情况下不显示此列是很糟糕的。花了很多时间找到它。此外,“user unhandled exception”的含义还不清楚。我有一个任务取消的处理程序(类似于try task.Wait(); catch ...
),并且任务中的 OperationCanceledException 在用户代码中被认为是未处理的。【参考方案4】:
如果我在此处的两行之间正确阅读,问题是您的异常实际上正在“消失”,即使默认调试器行为应该在未处理的异常上中断。
如果您有异步方法,您可能会遇到此问题,因为作为任务延续的一部分未在线程池线程上捕获的异常不被视为未处理的异常。相反,它们被吞下并与任务一起存储。
例如,看一下这段代码:
class Program
static void Main(string[] args)
Test();
Console.ReadLine();
private async static Task Test()
await Task.Delay(100);
throw new Exception("Exception!");
如果您使用默认调试器设置运行此程序(仅在未处理的异常上停止),调试器将不会中断。这是因为分配给延续的线程池线程吞下了异常(将其传递给 Task 实例)并将自身释放回池中。
请注意,在这种情况下,真正的问题是 Test()
返回的 Task
从未被检查过。如果您的代码中有类似类型的“即发即弃”逻辑,那么在抛出异常时您将看不到异常(即使它们在方法内“未处理”);只有当您通过等待、检查其结果或显式查看其异常来观察任务时,才会出现异常。
这只是一个猜测,但我认为您可能正在观察这样的事情。
【讨论】:
虽然这可能与操作的问题无关,但它提出了一个关于异步例程中引发的异常的非常好的观点。 有没有办法让调试器停止,即使异常是这样存储的? @Lucas,我不知道,尽管您可以通过一些代码更改来接近。如果你的即发即弃方法体有一个 try-catch 块,你可以添加一个显式的Debugger.Break()
调用。或者,您可以在TaskScheduler.UnobservedTaskException
处理程序中添加显式Debugger.Break()
,尽管这里的缺点是这可能会比原始异常晚得多,因为它会在清理任务时在终结器线程上发生。一般来说,您应该努力始终观察任务结果,或者至少在失败时记录一个 try-catch 块。【参考方案5】:
Visual Studio 中肯定存在一些错误,可能会导致它卡住,需要重新启动。甚至 VS2015。
我遇到了一个单线程情况,即 NullReferenceException
被“外部”处理程序(仍在我的代码中)捕获,尽管我要求它在引发时中断。
我意识到这是一个“已处理”异常,而您说的是“未处理”异常 - 但是我很确定有时快速重启 VS 会解决此问题,如果 IISRESET 没有。
【讨论】:
【参考方案6】:我遇到了同样的问题,我设法通过这样做解决了这个问题 -
-
按 Ctrl + Alt + e 调出
异常设置窗口。
勾选通用语言运行时异常。
就是这样!
我受到post 的启发,因为我使用的是 x64 版本的 Windows。
【讨论】:
这将导致它在所有异常上中断,即使是由用户代码处理的异常。 @carlin.scott,我相信您可以手动取消选中列表中处理的异常。 @JustinXL 问题是,这是一个按异常类型列出的列表,而不是按是否处理。例如,有时会处理System.ArgumentException
,有时则不会。我只关心在它不处理时打破它。
@JeradRose 当异常未处理时,调试器总是会中断。所以就像我说的,如果你不想中断处理的异常,只需从 抛出时打破列表。
即使在检查所有内容时,它也不会因异常而中断:/只是退出【参考方案7】:
这有点令人困惑,在我看来不如旧的异常对话框好,但无论如何。
如果异常在列表中并且被勾选,那么只要抛出异常,调试器就会中断。
如果一个异常未勾选或不在列表中,则调试器只会在该异常类型为用户未处理时中断。
例如,在下面的屏幕截图中,只要抛出 System.AccessViolationException
,调试器就会中断,但对于所有其他异常,只有在用户未处理异常时才会中断。
【讨论】:
【参考方案8】:微软已经巧妙地改变了新例外窗口中的逻辑。
见http://blogs.msdn.com/b/visualstudioalm/archive/2015/02/23/the-new-exception-settings-window-in-visual-studio-2015.aspx
关键部分是:
重要提示
这个新窗口包含与旧模式对话框相同的所有功能。调试器的任何功能都没有改变,只是您可以访问它们的方式 当异常未处理时,调试器总是会中断 如果调试器因用户未处理的异常中断而更改的设置已移至上下文菜单下 菜单位置已移至调试 -> Windows -> 异常设置
然而,如果像我一样,您的代码中有一个全局未处理异常处理程序,那么该列表中的第二项是关键:对我来说,因此不会有任何异常真正未处理,这似乎与VS2013不同。
要恢复 VS 在未处理的异常上中断的行为,我必须勾选我想要中断的所有异常类型,然后确保“附加选项”(您可能需要使此列可见*) NOT 设置了“在用户代码中未处理时继续”。 VS2015 逻辑 不 似乎认为我的 Global Unhandled Exception Handler 是“在用户代码中处理的”,所以它确实打破了这些;但它不会因捕获的异常而中断。这使它像 VS2013 一样工作。
*如何启用“附加操作”列
【讨论】:
这与 VS2013 不完全一样,因为它会根据您建议的设置中断用户处理的异常,而过去不是这种情况。 如何使“附加选项”列可见? @DaveInCaz 右键单击列标题>“显示列”>“附加操作”【参考方案9】:根据我的经验,如果您更改任何内容,2015 年的异常设置就会完全失控。
预计如果您直到父组“CLR”,那么您不应该得到任何未处理的破坏性执行。如果异常未处理,您将始终中断。但是,如果您未勾选 CLR 组,则 try...catch 中的代码根本不应该导致中断。事实并非如此。
解决方法:在新的异常设置工具箱中,右键选择“恢复默认”。 Taadaaaa...它再次正常运行。现在不要搞砸了。
【讨论】:
【参考方案10】:当我升级到 VS2015 时,我还遇到了一些问题,即用于“破坏”应用程序的异常,但现在被忽略并直接忽略了。有时我们希望我们的代码有意在我们希望代码停止而不是继续的地方抛出异常。我们总是使用短语Throw New Exception("Message")
来故意破坏我们的代码:
If SomethingReallyBad = True Then
Throw New Exception("Something Really Bad happened and we cannot continue.")
End If
在 VS2015 中,当我们说 Throw New Exception
时会抛出经典的“System.Exception”。因此,我们需要在新的异常设置中勾选“System.Exception”:
Check the System.Exception Box
检查后,我们的代码按预期运行。
【讨论】:
【参考方案11】:解决方案是在语义上与您认为的设置相反。您需要确保在用户代码中未处理时继续未启用即未选中,如其他操作下所示> 异常设置选项卡中的列 - 见下文:
您实际上是在说在代码中未处理时不要继续(即中断)
为此:
-
右键单击您关心的异常或一组异常(即通常在树中的顶行“公共语言运行时异常”)
选择选项在用户代码中未处理时继续(见下文)
确保未检查异常(见下文)
继续调试
这对我有好处 - 又开心了。
这是在 VS 2015 中
【讨论】:
【参考方案12】:Visual Studio 2017 可以很好地处理错误。另一方面,Visual Studio 2015 对任务的错误处理很糟糕,因为在调试模式下,异步任务中发生的所有异常都会被捕获,但是如果我越过它,它就会无限期地挂起。如果在没有调试的情况下执行,它会无限期挂起,没有捕获到异常!!!我喜欢 Visual Studio,并且自 1995 年以来一直在使用它,尽管我从 2010 年直接跳到 2015 年,但 2015 年是迄今为止最差的版本。我花了 8 个小时试图让这个异常处理工作没有成功。我在家用电脑上将确切的代码复制到 2017 年,它运行良好。我对微软将任务推入 2015 编译器无法正确处理的框架感到非常恼火。
【讨论】:
以上是关于Visual Studio 2015 中断未处理的异常不起作用的主要内容,如果未能解决你的问题,请参考以下文章
防止 Visual Studio 调试因明显的“未处理异常”而中断
即使在 C# 代码中处理,InvalidOperationException 也会导致 Visual Studio 中断
Visual Studio 2017 安装中断 Visual Studio 2015 ASP.NET Core 项目