在Visual Studio 2012中进行调试时,我可以将某些代码标记为可选吗?

时间:2013-10-14 13:02:51

标签: debugging visual-studio

我不确定如何真正地将我的问题写成文字,所以让我试着用一个例子来解释它:

让我们说我的程序在特定的操作中遇到了一些奇怪的行为。我已经找到了一些导致这种奇怪行为的代码。禁用此序列时,我不会遇到此行为。不幸的是,我需要这个代码,因为其他东西不起作用。

所以,接下来要做的是弄清楚当代码摘录处于活动状态时出现异常的原因。

为了更好地了解正在发生的事情,我有时想要执行整个操作,包括“错误的代码”和#39;有时没有。然后我可以比较结果,例如UI中发生的事情或我的函数返回的内容。

我想到的第一种方法是在启用代码的情况下运行我的程序,执行任何我想要的操作,然后停止我的程序,注释掉代码,重新编译并再次运行。嗯......听起来很蠢。特别是如果我再次需要打开该代码以查看另一个时间的其他行为,然后再次关闭,打开和关闭等等。

我不能选择使用断点并影响语句顺序或修改值,以便我运行或不运行if语句,for-loops等两个例子:

  • 我调试时序关键行为,当我停止程序时,时序发生了显着变化。因此,我可以设置的第一个断点必须位于操作的末尾。 1
  • 我希望出现一个工具提示或其他窗口,这些窗口被“抑制”#39;当焦点被赋予VS.因此,我根本不能使用任何断点。无论是在行动的开头还是在行动的最后阶段。 1

Visual Studio 2012中是否有任何技术允许我将此代码标记为可选,我可以在执行操作之前决定是否要运行此代码序列 ?我想到了更高级别的if(true|false)


我没有找到需要多次重新运行程序的解决方案。在这种情况下,我仍然可以使用#if false简单地评论代码。


1 请注意,当我需要在特定位置查看特定变量时(如果我还没有将值写入输出中),我可能会设置断点但是将再次关闭断点以一次完成整个动作。

8 个答案:

答案 0 :(得分:5)

在Visual Studio调试器中,您可以在“相关代码”前面设置断点。当代码在此时停止时,您可以选择让它继续,或者您可以右键单击任何其他行并选择Set Next Statement

这是一种奇怪的选择,但我开始欣赏它。

答案 1 :(得分:5)

  

我想到了更高层次上的if(true | false)。

为什么“在更高层次上”?为什么不使用这个呢?

您希望有时执行一段代码,有时不需要,并且应该在运行时更改开关,而不是在编译时 - 这显然会导致

if(condition)
{
    // code in stake
} 

这里的问题是您将使用的condition类型 - 可能是您在代码的发布版本中设置为true的变量,有时在您的调试版本中设置为false 。也许值来自配置文件,可能来自环境变量,可能由程序中的某种逻辑计算,无论何时何地。

编辑:您还可以在代码中为condition引入一个布尔变量,默认情况下将其初始化为true,并随时使用调试器更改其值。

答案 2 :(得分:5)

我能想到的唯一选择是在UI上添加一些只在调试时出现的内容,让您可以选择包含/排除相关操作。

当您使用它时,您可能还希望启用从UI重置应用程序到“已知状态”。

答案 3 :(得分:4)

Preprocessor Directives可能就是你所追求的。它们是执行编译器的代码,可以通过#字符开头来识别(在风格上,默认情况下它们不遵循代码的缩进模式,而是始终坚定地站在编辑的左边缘:)

#define INCLUDE_DODGY_CODE

public void MyMethodWithDodgyBits() {
#if INCLUDE_DODGY_CODE
    myDodgyMethod();
#endif
    myOkMethod();
}

在这种情况下,如果包含#define INCLUDE_DODGY_CODE,则myDodgyMethod()调用将被编译到您的程序中。否则,编译器将跳过调用,并且二进制文件中不会存在该调用。

答案 4 :(得分:3)

您可以根据自己的要求进行调试。

  1. Visual Studio有许多选项可以直接浏览代码。您可以使用Set Next Statement功能直接转到特定语句。您还可以通过Immediate Window QuickWatch和调试时悬停在变量上的工具提示直接编辑值。

  2. Visual Studio还具有回放执行历史记录的功能。看看IntelliTrace即可开始使用。当您有多个相互关联的区域进行交互并生成错误条件时,它会很有帮助。

  3. 您还可以在条件块中包装代码段,并根据需要设置条件变量。这可能是在您调试时,或者您可以通过配置文件传递参数。如果您希望排除多个语句,则使用条件检查可能比手动单步执行代码更容易。

答案 5 :(得分:0)

它有时取决于VS的版本和语言,但您可以愉快地编辑代码(将其注释掉,或将其包装在一个大的#ifdef 0中)然后按alt + F10并编译器将重新编译,重新链接并继续执行,好像你从来没有摆弄过它。

但是虽然这在VC ++中运行得很好(从VS v6 IIRC开始),C#可能有问题 - 我发现(使用VS2010)我无法编辑并以这种方式继续使用包含任何lambda(主要是linq)语句的函数,以及64比特代码从来没有用过这个。尽管如此,它值得尝试,因为它有时非常有用。

答案 6 :(得分:0)

我已经处理过具有用于单独调试的可选代码的应用程序,这些代码不应出现在生产环境中。这段可选代码对我们来说最容易使用配置文件来控制,因为它不需要重新编译来改变。

这样的修复可能不是最终结果的全部结果,但它可能有助于完成它直到找到修复程序。如果你有多个需要组合测试的可选部分,这种修复方式可能需要配置文件中的多个键,这可能是一个缺点,并且很难跟踪。

答案 7 :(得分:0)

你的问题并不完全清楚,这可能就是为什么有这么多你认为无效的答案。如果没有人能够回答这个问题,你可能会考虑重新措辞。

由于存在另一个无效答案的风险,我将在过去如何处理该问题时添加一些意见。

最简单的方法是在

中放置任何可选代码
#if DEBUG
    //Optional code here
#endif

这样,当你在调试模式下运行时,代码就会被实现,当你在发布模式下运行时,它就不会。在两者之间切换需要单击一个按钮。

我也用一个简单的标志以类似的方式解决了同样的问题:

bool runOptionalCode = false;

然后

if (runOptionalCode)
{
    //Place optional code here
}

同样,在模式之间切换需要更改一个单词,因此这是一项简单的任务。你在你的问题中提到了这一点,但是由于原因尚不清楚而给予折扣。正如我所说,在两者之间切换需要很少的努力。

如果您需要在代码运行时进行更改,最好的方法是使用UI项目或键击来修改上面示例中提到的标志。取决于您的应用程序,虽然这可能比它的价值更多的努力。在过去,我发现当我有一个关键监听器已经作为项目的一部分实现时,有几个关键笔划决定是否运行我的调试(可选)代码效果最好。在没有关键听众的应用程序中,我宁愿坚持使用以前的方法之一。