我该如何排除这个规则中的一个异常?我的代码中有一个被捕获的异常是程序逻辑的一部分。因此,每次命中它时,我显然不想让该异常停止调试器。
例如:我要忽略第344行上被捕获的空引用异常,并希望在所有其他异常处停止。
DebuggerHidden
是你的好朋友!
公共语言运行时对该属性没有语义,它是提供给源代码调试器使用的。例如,Visual Studio 2005 调试器不会在标记有此属性的方法中停止,并且不允许在该方法中设置断点。Visual Studio 2005 调试器识别的其他调试器属性包括
DebuggerNonUserCodeAttribute
和DebuggerStepThroughAttribute
。
在 VS2010 上测试,并且效果很好。
尽管 DebuggerStepThrough
对某些特定的调试器版本也可以起作用,但根据两个答案的评论,DebuggerHidden
似乎适用范围更广。
请注意,两种选项目前均不适用于迭代器块方法或异步 / 等待方法。这可能会在 Visual Studio 的后续更新中修复。
请注意,在 .NET Core + Rider 结合的情况下,此功能无法使用,您可以投票支持该问题。
如果我没有记错的话,你可以在包含你不想要异常触发的代码的方法上使用 DebuggerStepThrough
属性。我想你可以将触发烦人异常的代码隔离到一个方法中,并对其进行修饰。
DebuggerStepThrough
属性不会影响调试器对第一次机会异常的行为。 - Michael PetrottaDebuggerStepThrough
属性对CLR没有意义,它只在调试器中被解释。看起来在各种情况下它并不可靠,在这种情况下,使用DebuggerHidden
属性可以可靠地工作。参考链接:https://dev59.com/VXM_5IYBdhLWcg3wUxnF#3455100 - Eric J.在其他答案中指定的属性(以及其他属性,例如DebuggerNonUserCode
属性)在Visual Studio 2015中默认情况下不再以相同的方式工作。调试器将在标有这些属性的方法中断异常,与旧版本的VS不同。要关闭改变它们行为的性能增强功能,您需要更改注册表设置:
reg add HKCU\Software\Microsoft\VisualStudio\14.0_Config\Debugger\Engine /v AlwaysEnableExceptionCallbacksOutsideMyCode /t REG_DWORD /d 1
更多信息可以在Visual Studio博客上找到。
(这可能应该是置顶答案的评论,但我没有足够的声望)
reg add HKCU\Software\Microsoft\VisualStudio\14.0_Config\Debugger\Engine /v AlwaysEnableExceptionCallbacksOutsideMyCode /t REG_DWORD /d 0
(即将最终值设置为0)将重新启用它。 - bhhDebuggerStepThrough是用于防止在try/catch方法中调试器中断的属性。
但是它只在Visual Studio Debugging选项的General设置(菜单Tools/Options,节点Debugging/General)中未取消选中“启用Just My Code(仅托管代码)”选项时才起作用...
关于该属性的更多信息请参见http://abhijitjana.net/2010/09/22/tips-on-debugging-using-debuggerstepthrough-attribute/
DebuggerHidden仅会防止调试器显示抛出异常的方法。相反,它将显示堆栈上未标记该属性的第一个方法...
我在VS 2019中找到了一个解决方案,虽然有点复杂,但对于我的用例来说,解决这个问题是必要的。
首先将导致问题的代码移到自己的函数中,这样可以避免在周围代码中抑制异常,并使用DebuggerStepThrough属性(或DebuggerHidden也可以)标记它。
[DebuggerStepThrough]
public void ExceptionThrowingFunction()
{
//.. Code that throws exception here
}
OutsourceException(ExceptionThrowingFunction);
那么,您可以选择一个独立的项目(模块),或者是您不关心抑制所有异常的项目,或者是专门为此目的创建的项目。重要的是这个项目必须是单独的,这样您的主项目仍然可以在这种异常类型上中断。在我的情况下,我已经有了一个名为SharedFunctions的小型实用程序项目,所以我把它放在那里。该代码非常稳定,大多数时候不需要调试。
在一个名为ExceptionUtils的类中,我添加了以下函数:
public static T OutsourceException<T>(Func<T> func)
{
T result = default;
try
{
result = func.Invoke();
}
catch { }
return result;
}
public static T OutsourceException<T, Y>(Func<T, Y> func, Y arg)
{
T result = default;
try
{
result = func.Invoke(arg);
}
catch { }
return result;
}
public static void OutsourceException<T>(Action<T> action, T arg)
{
try
{
action.Invoke(arg);
}
catch { }
}
你可能需要添加更多这样的内容,这些只涵盖了函数中有0-1个参数的基本情况。
最后,当你运行代码时,它仍然会在Outsource函数中出现异常,并显示如下消息:。如果你勾选底部的复选框(例如'SharedFunctions.dll'),它将添加一个规则,即如果从该程序集抛出异常,则应忽略该异常。一旦勾选此项,异常应该被抑制。所有其他主程序集中的此类异常仍将像往常一样中断。
由于VS 2015中的更改破坏了[DebuggerHidden]和类似属性(请参见链接到另一个答案的博客文章),因此这些属性现在将异常传递给调用类,调试器只是在那里中断。如果我们将调用类移动到另一个程序集中,就可以使用异常条件系统来抑制异常。
有些异常无法完全从代码中删除,例如在UWP应用程序中尝试访问Package.Current
时。它将始终在调试器中引发异常,这只能由Microsoft解决。在这种情况下的另一种解决方案是将其用#if !DEBUG
包围起来,但在其他情况下,这并不实用。