Visual Studio 2008中的If语句问题

11

我遇到了一个非常奇怪的问题,甚至录下了我的会话,因为我认为没有人会相信我。

我遇到了一个似乎在非常基础的层面上存在的错误。这是一个单线程应用程序,我所做的就是求值一个布尔值。

这个布尔值等于false,然而,if语句却像它是true一样执行...你会明白我的意思的。我已经多次清理并重新构建解决方案,但毫无头绪。

请给我一些解释,谢谢。

http://www.youtube.com/watch?v=ope9kxEyt4g


你使用的是哪个版本的VS?你是否已经安装了最新的服务包? - Mitch Wheat
你能发布一下这段代码生成的IL吗? - Maximilian Mayerl
我几个月前在SO上看到了另一个关于同样情况的问题,但是我找不到它来查看原因/解决方案。 - adrianbanks
附带问题:你用什么工具制作了这个视频?帧速率看起来比我用Camtasia管理的要流畅。 - Lasse V. Karlsen
你是否使用像PostSharp这样的AOP工具,在构建过程中修改程序集?从你点击调试按钮到代码开始运行的时间来看,似乎并没有使用,但在某些情况下,这些工具可能会影响调试器与源代码行相关的可执行代码位置。 - Lasse V. Karlsen
6个回答

8
我曾多次见过这种情况。基本上,你正在调试的代码与你看到的代码不匹配。
我不知道是什么原因导致这种情况,解决方案遵循货车式模仿指南。
  • 关闭所有Visual Studio的副本
  • 删除此项目的所有bin和object文件夹
  • 删除所有.NET项目的bin和object文件夹
  • 删除“C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files”中找到的所有文件

我已经删除了bin文件夹中的所有文件,但我完全忘记了obj和临时asp文件。我会尝试一下。我仍然不明白为什么硬编码false会产生期望的结果,或者为什么加入else语句会解决问题。 - user76071
很抱歉我不得不投下反对票,但事实证明做所有这些事情仍然没有解决问题。我已经删除了所有的bin文件夹、Obj文件夹、所有临时asp文件(包括x86和x64),但问题仍然存在。 - user76071
2
真遗憾。如果您找到了其他的答案,请告诉我。 - Jonathan Allen

6

我猜测在部署过程中发生了一些奇怪的事情,因此pdb与实际代码不同步。如果您使用日志记录而不是调试器来确定发生了什么,我认为您将看到更合理的行为。我怀疑这不是CLR本身在处理“if”时表现出奇怪的行为 - 更有可能是调试器/运行时不一致。


我已经自己清空了bin文件夹,我们正在谈论一个全新的构建。我喜欢加入调试语句来查看发生了什么。我会尝试一下。谢谢Jon。 - user76071
同意。我正在升级的ASP.NET应用程序有时会使调试器出现一些问题。最简单的例子是当您在方法中插入一些代码,开始调试并看到那些行从未执行 - 它们只是被跳过了。或者当调试器突出显示一行但实际上执行下一行时。 删除obj/和bin/文件夹总是对我有帮助。 - Audrius

3

我很久以前看到过类似的情况,是在Delphi中,所以我的问题是:你是在编译Release还是Debug版本?是否进行了优化?

我问这个问题的原因是,在一次调试会话中,我发现了一个只有4-5行代码的小程序,根据调试器的显示,它似乎是反向执行的。

基本上,以下类型的代码:

procedure Test;
begin
    Line1;
    Line2;
    Line3;
    line4;
end;

根据调试器显示,执行顺序如下:
procedure Test;
begin             start -+
    Line1;               |                             +-> here -+
    Line2;               |                   +-> here -+         |
    Line3;               |         +-> here -+                   |
    line4;               +-> here -+                             |
end;                                                             +-> end

原因是这些行之间没有副作用,所以编译器通过重写代码来“优化”它,实际上重新排列代码以使其看起来完全倒序执行。因此,你是否在后面有一个throw语句,实际上正在执行的是那个throw语句,但由于代码重排,两个throw语句只被编译一次作为可执行代码?注意:我没有任何理由知道Visual Studio正在做什么,但当我看到你的视频时,这就是我想到的。

0

我一个星期前也遇到了完全相同的问题。同时拥有VS2008,最新的SP。WinForms应用程序。值为false,但是if语句却总是被执行。我正在进行与您视频中一样的调查。这里是我的代码片段:

 if (CurrentFileFormatVersion > int.Parse(metaInfo.SimulationFileVersion))
     throw new SimulationFormatException(ws, ss);

以“Release”方式编译的无调试器运行正常,请尝试。

我想VS2008调试器中有一个错误。在使用“if”和“throw”关键字时,可以以某种方式复现。

编辑:上面的“executed”一词是错误的,当然应该使用“已步入但未执行”的表述。


1
if-block 真的被执行了吗?还是只是被调试器突出显示了?在 Vince 的视频中,代码似乎没有被执行(异常对象 e 为 null)。 - Dirk Vollmar

0

针对代码的奇异高亮现象,我也来一句“我也有这个问题”。我正在运行VS2008和C#。我的Windows Forms项目引用了另一个项目中的类库,并且我正在逐行调试两个项目。在某个时候,黄色高亮在调试时与实际执行的代码行相差了14到20行。

我关闭了VS,打开了两个项目的目录,并删除了bin/Debug和obj/Debug中的所有内容,然后重新启动了VS。在重新编译和逐步调试时,一切都正常了。

我不知道问题是在.manifest、.pdb还是.Cache文件中。这不重要。把它们全部删掉,然后就没问题了。

顺便说一句,谷歌几乎没什么用处,除了返回了这个SO线程之外。所有其他结果都是关于VC++模板和VS2005存在问题的,在那里一个SP修复了那个问题。这不是同样的问题。


我放弃了这个问题。我尝试了所有的方法,清除了临时互联网文件中的所有DLL,清除了Bin中的所有本地文件,甚至将解决方案移动到另一台电脑上。问题似乎出现在调试器中,原因不明。 - user76071

0

我认为这看起来像是调试步骤范围不正确的情况。你不能总是相信调试器中的黄色高亮显示。你实际上没有进入到代码中。在 F# 的早期测试版中,我们遇到了很多类似的错误,其中黄色高亮会像疯了一样跳来跳去。调试器的高亮大多取决于编译器写入 .pdb 文件的“源范围”,该范围对应于特定编译指令集。

这是哪个版本的 VS/C#?

编辑 看到其他人的答案后,确实可能的原因是您的 .pdb 文件与您的 .dll 不同步。


我会尝试在下周一回去工作时清除obj文件以及所有其他临时和生成的文件。 我会随时更新大家。 - user76071

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接