我希望能够在调试时打破异常......就像在 Visual Studio 2008 的菜单调试/异常对话框中一样,除了我的程序在我想要调试的位之前有许多有效的异常。
因此,不是每次都使用对话框手动启用和禁用它,而是可以使用#pragma 或其他方法自动执行它,这样它只发生在特定的代码段中?
我希望能够在调试时打破异常......就像在 Visual Studio 2008 的菜单调试/异常对话框中一样,除了我的程序在我想要调试的位之前有许多有效的异常。
因此,不是每次都使用对话框手动启用和禁用它,而是可以使用#pragma 或其他方法自动执行它,这样它只发生在特定的代码段中?
接近此的唯一方法是将 DebuggerNonUserCodeAttribute 放在您的方法上。
这将确保标记方法中的任何异常都不会导致异常中断。
很好的解释在这里...
这是您针对一种方法设置的属性,以告诉调试器“与我无关'。不是我的代码!”。容易上当的调试器会相信你,并且不会中断该方法:使用该属性会使调试器完全跳过该方法,即使您正在单步执行代码;发生的异常,然后在方法中被捕获,不会闯入调试器。它会将其视为对框架程序集的调用,并且如果异常未处理,则会在调用该方法的代码中向上一级报告调用堆栈。
代码示例:
public class Foo
{
[DebuggerNonUserCode]
public void MethodThatThrowsException()
{
...
{
}
条件断点呢?如果我理解正确,只有当某个变量或表达式的值为 true 时,才能触发断点。
在#if DEBUG 中包装你的try catch 块
public void Foo()
{
#if DEBUG
try
#endif
{
//Code goes here
}
#if DEBUG
catch (Exception e)
{
//Execption code here
}
#endif
}
我喜欢将花括号保留在#if 之外,这样,无论在调试内部还是外部,它都可以将代码保持在相同的范围内。
如果您仍然想要执行处理但想要更多详细信息,您可以这样做
try
{
//code
}
catch (FileNotFoundException e)
{
//Normal Code here
#if DEBUG
//More Detail here
#endif
}
#if DEBUG
catch (Exception e)
{
//handel other exceptions here
}
#endif
这对你来说有点晚了,但这是我经常尝试教人们保守地使用异常的最大原因。仅在发生灾难性事件并且您无法合理继续时才使用异常。
在调试程序时,我经常打开 First Chance Exceptions (Debug -> Exceptions) 来调试应用程序。如果发生了很多异常,则很难找到“错误”的地方。
此外,它会导致一些反模式,例如臭名昭著的“catch throw”,并混淆了真正的问题。有关这方面的更多信息,请参阅我就该主题发表的博客文章。
就您的问题而言,您可以仅针对特定类型的异常打开第一次机会调试。除非其他异常属于同一类型,否则这应该可以正常工作。
您也可以使用断言而不是断点。例如,如果您只想在第二次调用该函数时在循环的第 5 次迭代中设置断点,您可以执行以下操作:
bool breakLoop = false;
...
Work(); // Will not break on 5th iteration.
breakLoop = true;
Work(); // Will break on 5th iteration.
...
public void Work() {
for(int i=0 ; i < 10 ; i++) {
Debug.Assert (!(breakLoop && i == 5));
...
}
}
所以在第一次调用 Work 时,当 breakLoop 为 false 时,循环将在没有断言的情况下运行,第二次循环将中断。