Visual Studio 2015在未处理的异常上无法正常工作


114

Visual Studio以前有一个特定的复选框用于“在未处理的异常时中断”。在2015年,它已被删除(或移到了我找不到的地方)。因此,如果我未能提供用户级异常处理程序,那么现在转换后的项目将不再中断。我不想破坏所有“抛出的异常”,因为我处理特定的异常。只是在我无法提供特定处理程序的地方。

现在,我的代码只是退出当前过程,并在下一个调用堆栈位置继续执行,而不是良好。

有人知道如何在Visual Studio 2015中重新获得它吗?我昨天刚升级到社区版。


Visual Studio 2015将保留先前版本的当前布局,如果ToolWindow选项卡不具有所有所需的位置。在您的情况下,您正在寻找“ 例外设置”
格雷格

4
@greg,不是我不知道在哪里可以找到面板。我担心的是,我要寻找的行为不在该面板中。
泰德·洛里

这里同样的问题。在我们的情况下,当autofac未注册所有类型时,我们预计会发生异常中断。在vs2013中使用相同的解决方案可以正常工作,在vs2015中我们什么也没得到。这也是其他第三方注册和例外(例如nservicebus)的问题。我想知道是否仅在vs2013中创建并在vs2015中运行的项目是这种情况
Choco Smith

3
新的工具窗口确实很烂。
割让

根据MS异常分类,如果您有未处理的异常,则它总是会破坏调试器。可能是您必须在“选项->调试->常规”列表中选中选项“当排泄物穿过AppDomain时断裂...”。
tsul 2016年

Answers:


118

开始调试时,默认情况下会在右下方窗格中显示一个名为“异常设置”的新窗口。它具有您期望的所有选项。

您可以使用CTRL+ ALT+E

这使您可以选择哪些异常导致调试器中断。

但是,关键在于,您还可以设置这些异常是始终中断还是仅在它是未处理的异常时才中断-但设置该字段不是很直观。

您需要首先在工具>选项>调试下选中“仅启用我的代码”。

然后,您可以在新的“例外设置”窗口中右键单击列标题(“抛出时中断”),并添加“其他操作”列,然后将每个例外设置为“在用户代码中未处理时继续”。

因此,只需右键单击异常或整个组,然后禁用“在未处理用户代码时继续”标志。不幸的是,“其他操作”列将显示为空,与“在用户代码中未处理时中断”相同。

在此处输入图片说明

有关此的更多信息:

http://blogs.msdn.com/b/visualstudioalm/archive/2015/02/23/the-new-exception-settings-window-in-visual-studio-2015.aspx


7
实际上,该窗口仅具有“中断抛出”的选项。那不是我想要的。我想要“不处理时破裂”。
泰德·洛里

17
这就是问题所在。它不会破坏。如我上面所说,它退出(退出)当前过程调用,并开始执行调用过程中的下一行代码。
泰德·洛里

2
而且我确实启用了“仅我的代码”。
泰德·洛里

19
@TomStudee我也有同样的问题。我想要的是“未处理时破裂”,但我得到的是“抛出时破裂”。问题是:如何获得“未处理时破裂”?
ogggre 2015年

1
@TomStudee我刚刚添加了一些急需的说明,因为您缺少允许您将异常设置为仅在未处理时才中断的关键设置。
Jerad Rose

36

我遇到了同样的问题,因此我设法解决了这个问题-

  1. Ctrl+ Alt+ e弹出“ 例外设置”窗口。
  2. 勾选公共语言运行时异常在此处输入图片说明

而已!

我的灵感来自这个职位,因为我使用的Windows版本的x64


7
这将导致它在所有异常上中断,即使是由用户代码处理的异常也是如此。
carlin.scott 2016年

1
@ carlin.scott,我相信您可以手动取消选中从列表处理的异常。
贾斯汀XL 2016年

6
@JustinXL问题是,这是一个按异常类型而不是是否处理的列表。例如,有时会System.ArgumentException被处理,有时会被处理。我只关心在处理时中断。
杰拉德·罗斯

1
@JeradRose 未处理异常时,调试器将始终中断。因此,就像我说的那样,如果您不希望中断处理的异常,只需从“ 抛出时中断”列表中取消选中该异常类型即可。
贾斯汀XL

即使在检查所有内容时也没有遇到异常:/只是退出
Douglas Gaskell

10

对于只希望在异常涉及其代码时才中断的Googler,Visual Studio 2015中提供了一个选项:选项->调试->常规->我的代码。一旦检查,它允许在代码之外管理(抛出和捕获)异常时不中断。


这使我避免了另一种情况,VS2015由于某种原因拒绝输入某些代码。该代码是“我的代码”,但触发了“仅我的代码”标志。我猜想在运行2个VS实例和一个独立的Web服务器以及其他一些实例时某个地方存在一个错误。
LosManos

9

Microsoft在新的“例外”窗口中巧妙地更改了逻辑。

参见http://blogs.msdn.com/b/visualstudioalm/archive/2015/02/23/the-new-exception-settings-window-in-visual-studio-2015.aspx

关键部分是:

重要笔记

  • 这个新窗口包含与旧模式对话框相同的功能。调试器的功能仅更改了您访问它们的方式,就没有改变
  • 当未处理异常时,调试器将始终中断
  • 如果调试器因用户未处理的异常而中断,则更改的设置已移至上下文菜单下
  • 菜单位置已移至“调试”->“ Windows”->“例外设置”

但是,如果像我一样,您的代码中有一个全局未处理的异常处理程序,那么该列表上的第二项是关键:对我而言,因此不会真正处理任何异常,这似乎与VS2013不同。

要恢复VS在未处理的异常上中断的行为,我必须勾选要中断的所有异常类型,然后确保“继续”的“附加选项”(您可能需要使该列可见*)在用户代码未处理时”被设定。VS2015逻辑似乎不认为我的全局未处理异常处理程序是“在用户代码中处理的”,因此它确实在这些代码上中断了;它不会中断捕获到的异常。这使其像VS2013一样工作。

*如何启用“其他操作”列 *如何启用“其他操作”列


2
这与VS2013并不完全一样,因为它会打破用户使用您建议的设置处理的异常,而过去并非如此。
carlin.scott

如何使“其他选项”列可见?
UuDdLrLrsS

@DaveInCaz右键单击列标题>“显示列”>“其他操作”
oatsoda

7

如果我在这里正确地阅读了两行之间的问题,那么问题是即使默认调试器行为应在未处理的异常上中断,您的异常也实际上“消失了”。

如果您具有异步方法,则可能会遇到此问题,因为作为任务延续的一部分未在线程池线程上捕获的异常不被视为未处理的异常。而是将它们吞下并与任务一起存储。

例如,看下面的代码:

class Program
{
    static void Main(string[] args)
    {
        Test();
        Console.ReadLine();
    }

    private async static Task Test()
    {
        await Task.Delay(100);
        throw new Exception("Exception!");
    }
}

如果使用默认调试器设置运行该程序(仅在未处理的异常时停止),调试器将不会中断。这是因为分配给延续的线程池线程吞下了异常(将其传递给Task实例)并将其释放回该池。

请注意,在这种情况下,真正的问题是,从不检查Taskreturn by Test()。如果您的代码中有类似类型的“一劳永逸”逻辑,那么在抛出异常时就不会看到它们(即使方法内部未处理)。仅当您通过等待任务,检查其结果或显式查看其异常来观察任务时,才会显示该异常。

这只是一个猜测,但我认为您可能正在观察这样的情况。


尽管这可能与op的问题无关,但它对异步例程中引发的异常提出了很好的建议。
Phil Cooper

即使这样存储异常,有没有办法使调试器停止?
卢卡斯

@Lucas,虽然您可以通过一些代码更改来接近,但我不知道。如果即弃即用方法主体具有try-catch块,则可以添加显式Debugger.Break()调用。或者,您可以Debugger.Break()TaskScheduler.UnobservedTaskException处理程序中添加一个显式控件,尽管这样做的缺点是,它可以比原始异常触发得晚得多,因为它在清理Task时在终结器线程上发生。通常,您应该努力始终观察Task的结果,或者至少在失败时记录一个try-catch块。
丹·科比

3

以我的经验,如果您进行任何更改,2015年的异常设置将完全被淘汰。

可以预料的是,如果您直到父组“ CLR”,您都不会因为未处理而得到任何中断执行。如果未处理异常,您将始终中断。但是,如果您未选中CLR组,则try ... catch中的代码根本不会引起中断。事实并非如此。

解决方案:在新的例外设置工具箱中,右键单击并选择“恢复默认值”。Taadaaaa ...它再次恢复正常。现在不要拧它。


1

尝试按照说明进行操作:

  1. 在“例外设置”窗口中,右键单击窗口,然后选择“显示列”,以打开上下文菜单。(如果您关闭了“我的代码”,则不会看到此命令。)
  2. 您应该看到第二列名为“其他操作”。当用户代码未处理特定异常时,此列显示“继续”,这意味着如果该异常未在用户代码中处理但在外部代码中处理,则调试器不会中断。
  3. 您可以更改此设置以用于特定的异常(选择异常,单击鼠标右键,然后在未处理用户代码时选择/取消选择“继续”),也可以更改整个异常类别(例如,所有公共语言运行时异常)。

https://msdn.microsoft.com/zh-CN/library/x85tt0dd.aspx


完全同意。默认情况下不显示此列是很糟糕的。花了很多时间找到它。顺便说一句,“ 用户未处理的异常 ”的含义还不清楚。我有一个任务取消的处理程序(类似try { task.Wait(); } catch { ... }),该任务中的OperationCanceledException被认为在用户代码中未处理。
tsul 2016年

1

一切都令人困惑,我认为它不如旧的异常对话框好,但无论如何。

如果列表中有一个异常并选中该异常,则每当引发异常时调试器就会中断。

如果列表中没有出现异常,则调试器仅在用户未处理该异常类型时才会中断。

例如,在下面的屏幕截图中,调试器将在每次System.AccessViolationException抛出a时中断,但对于所有其他异常,只有在用户未处理该异常时,调试器才会中断。

Visual Studio 2015例外工具窗口


1

当我升级到VS2015时,我还遇到了一些问题,这些异常曾经用来“破坏”应用程序,但现在被忽略并直接传递。有时候,我们希望代码在我们希望代码停止而不是继续的地方故意抛出异常。我们总是使用该短语Throw New Exception("Message")来使我们的代码有意中断:

    If SomethingReallyBad = True Then
        Throw New Exception("Something Really Bad happened and we cannot continue.")
    End If

在VS2015中,当我们说时会抛出经典的“ System.Exception” Throw New Exception。因此,我们需要在新的“例外设置”中检查“ System.Exception”对勾:

选中System.Exception框

检查后,我们的代码按预期进行。


1

解决方案是,从语义上讲,这与您认为的设置相反。你需要确保在用户代码中未处理时继续未启用,即没有检查下如其他操作列中的例外设置选项卡-请看下图:

您实际上是在说不处理代码时不要继续(即中断)

例外设置窗口(Ctrl + Alt + E)

去做这个:

  1. 右键单击您关心的一个或一组异常(即通常在树中的第一行“公共语言运行时异常”)
  2. 选择选项在用户代码中未处理时继续(请参阅下文)
  3. 确保未检查异常(请参见下文)
  4. 继续调试

在此处输入图片说明

做到了,对我来说又开心了。

这是在VS 2015中


0

Visual Studio中肯定存在一些错误,可能导致其卡住而需要重新启动。甚至是VS2015。

我有一个单线程情况, NullReferenceException即使我要求在启动时将其中断,也被“外部”处理程序(仍在我的代码中)捕获。

我意识到这是一个“处理过的”异常,而您正在谈论的是“未处理的”异常-但是,我很确定,如果IISRESET没有,VS的快速重启有时会解决此问题。


0

Visual Studio 2017可以很好地处理错误。另一方面,Visual Studio 2015会沉迷于任务的错误处理,因为在调试模式下,异步任务中发生的所有异常都会被捕获,但是如果我跳过它,则会无限期地挂起。如果在没有调试的情况下执行,它将无限期地挂起,没有异常捕获!!!我喜欢Visual Studio,自1995年以来一直使用它,而2015年是最差的版本,尽管我从2010年直接跳到2015年。我花了8个小时试图使这种异常处理无法成功。我在家用计算机上将确切的代码复制到2017年,并且运行良好。我非常恼怒的是,Microsoft将任务推入了2015编译器无法正确处理的框架。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.