1

我不确定如何真正将我的问题用语言表达,所以让我尝试用一​​个例子来解释它:

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

所以,我接下来要做的是弄清楚为什么当代码摘录处于活动状态时会出现不同的情况。

为了更好地理解发生了什么,我有时想运行整个操作,包括“坏代码”,有时不运行。然后我可以比较结果,例如 UI 中发生了什么或我的函数返回什么。

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

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

  • 我调试了一个时序关键行为,当我停止程序时,时序发生了显着变化。因此,我可以设置的第一个断点必须在动作结束时。1
  • 我希望出现一个工具提示或其他窗口,当焦点被赋予 VS 时,它会被“抑制”。因此,我根本不能使用任何断点。无论是在动作的开始还是结束时。1

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


我不是在寻找需要多次重新运行程序的解决方案。在这种情况下,我仍然可以使用简单的方法来简单地用#if false.


1请注意,当我需要在某个位置查看特定变量时(如果我没有将值写入输出),我当然可以设置断点,但会再次关闭断点以运行整个操作去。

4

8 回答 8

5

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

这是一个奇怪的选择,但我已经开始欣赏它了。

于 2013-10-14T13:16:22.717 回答
5

我想到了更高层次的 if(true|false) 之类的东西。

为什么是“更高层次”?为什么不完全使用这个?

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

if(condition)
{
    // code in stake
} 

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

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

于 2013-10-14T13:39:40.653 回答
5

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

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

于 2013-10-14T14:19:14.813 回答
4

预处理器指令可能是您所追求的。它们是供编译器执行的代码片段,可以通过以#字符开头来识别(并且在风格上,默认情况下它们不遵循代码的缩进模式,而是始终牢牢地位于编辑器的左侧边缘) :

#define INCLUDE_DODGY_CODE

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

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

于 2013-10-14T13:32:36.473 回答
3

根据您的要求,有几个调试选项。

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

  2. Visual Studio 还具有回放执行历史的能力。查看IntelliTrace以开始使用。当您有多个关注领域正在交互并生成错误条件时,它会很有帮助。

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

于 2013-10-14T13:34:17.373 回答
0

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

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

于 2013-10-14T14:21:51.260 回答
0

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

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

于 2013-10-14T15:17:43.070 回答
0

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

冒着给出另一个无效答案的风险,我将添加一些关于我过去如何处理该问题的意见。

最简单的方法是在其中放置任何可选代码

#if DEBUG
    //Optional code here
#endif

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

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

bool runOptionalCode = false;

然后

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

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

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

于 2013-10-15T13:03:20.897 回答