DotNet启用优化时步骤不正确

时间:2016-07-18 04:54:59

标签: c# debugging optimization visual-studio-2015

我有一种情况,当打开优化(即处于发布模式)时,c#编译器正在做一些奇怪的事情,并且你开始逐步执​​行代码(启用我的代码关闭)

我的代码类似于以下内容,它的作用基本上是看设置提供程序是否具有它想要设置的应用程序环境,否则它会使环境单独使用。

var environmentValue = settingsProvider.ApplicationEnvironment;
if (!string.IsNullOrWhiteSpace(environmentValue))
{
    switch (environmentValue.ToLower())
    {
        case "p":
            _connectionSettings.Production();
            break;
        case "t":
            _connectionSettings.Test();
            break;
        case "d":
            _connectionSettings.Development();
            break;
        case "l":
            _connectionSettings.Local();
            break;
    }
}

然而,当启用优化时,即使environmentValue的值为null,它也始终会触及最后一个case语句,即不应该首先进入开关。

我不得不更改代码,以便它就像这样,现在它更符合默认值:case。

var environmentValue = settingsProvider.ApplicationEnvironment;
if (!string.IsNullOrWhiteSpace(environmentValue))
{
    switch (environmentValue.ToLower())
    {
        case "p":
            _connectionSettings.Production();
            break;
        case "t":
            _connectionSettings.Test();
            break;
        case "d":
            _connectionSettings.Development();
            break;
        case "l":
            _connectionSettings.Local();
            break;
        default:
            Console.WriteLine(environmentValue);
            break;
    }
}

我通过Visual Studio 2015,Framework 4.5.1版,发布模式,任何CPU(更喜欢32位)和启用Just My Code代码来运行它。

当我第一次开始这篇文章时,我没有意识到只有在单步执行代码时才会这样。它似乎确实有一些奇怪的行为,因为我没有单步执行代码并且仍在查看最后的案例陈述。

我还创建了一个说明问题的要点项目。

https://gist.github.com/matthewvukomanovic/899d595cd0b787116b95ddb5f2b128d3#file-program-cs

使用测试应用程序我已经编写了它之后只需要另一个调用它会强制它正常运行,但是在实际应用程序中它已经有其他使用同一个对象的调用,但它不能完全相同

除了添加像我这样的虚拟默认案例外,有没有人知道如何在单步优化代码时避免此问题?

1 个答案:

答案 0 :(得分:2)

这通常是发布内置代码的问题,the optimizer重新排序代码,这使得从可执行机器代码的映射回到程序中的源代码行模糊。这是调试配置首先存在的基本原因。单步和断点不是唯一行为不正常的调试功能,检查局部变量也会停止工作。

有一个调试器选项可以强制在使用调试器时禁用优化器,即使对于Release内置代码也是如此。使用工具>选项>调试>一般>勾选"抑制JIT优化"复选框。默认打开。启用该选项后,您的示例程序将正常运行。所以你可能已关闭它。

当您将调试器附加到正在运行的程序或使用Debugger.Break()中断时,该选项无法始终有效,无法工作。请记住,修改代码是非常不必要的。你可以从你的repro片段告诉它实际调用Local()方法。它只突出了错误的源代码行,这就是全部。模糊映射。请记住,当您调试代码的发布版本并且您将领先时,调试将会很糟糕。然后重新打开选项。