"无法评估表达式,因为当前方法的代码已优化"。意思是?

时间:2020-03-06 14:42:19  来源:igfitidea点击:

我编写了一些具有很多递归的代码,这需要花费大量时间才能完成。每当我"暂停"运行以查看发生了什么时,我都会得到:

Cannot evaluate expression because the code of the current method is optimized.

我想我明白那是什么意思。但是,令我感到困惑的是,在执行步骤后,代码不再"优化",而我可以查看变量。这是怎么发生的?代码如何在优化和非优化代码之间来回翻转?

解决方案

我们可能正在尝试在发布模式而不是调试模式下调试应用程序,或者在编译设置中启用了优化功能。

使用优化功能编译代码时,某些变量一旦在函数中不再使用,就会被丢弃,这就是为什么我们会收到该消息的原因。在禁用优化的调试模式下,不应出现该错误。

调试器使用FuncEval来允许我们"查看"变量。 FuncEval要求在GarbageCollector安全点在托管代码中停止线程。在IDE中手动"暂停"运行会导致所有线程尽快停止。高度递归代码将倾向于在不安全的地方停止。因此,调试器无法评估表达式。

按F10将移至下一个Funceval Safe点,并将启用功能评估。

有关更多信息,请查看FuncEval的规则。

我相信我们所看到的是优化的结果,有时变量会被重用,尤其是那些在堆栈上创建的变量。例如,假设我们有一个使用两个(局部)整数的方法。第一个整数在方法开始时声明,并且仅用作循环的计数器。第二个整数在循环完成后使用,它存储计算的结果,以后将其写出到文件中。在这种情况下,优化器可以决定重用第一个整数,并保存第二个整数所需的代码。当我们尝试尽早查看第二个整数时,我们会收到一条询问"无法求值表达式"的消息。尽管我无法解释确切的情况,但优化器有可能稍后将第二个整数的值传输到单独的堆栈项中,从而使我们能够从调试器访问该值。

当Debug.Break()行位于调用堆栈的顶部时,我们不能评估表达式。那是因为那条线被优化了。按F10键将有效的代码行移至下一行,手表将开始工作。

来自Microsoft的一位朋友的朋友发送了此邮件:
http://blogs.msdn.com/rmbyers/archive/2008/08/16/Func_2D00_eval-can-fail-while-stopped-in-a-non_2D00_optimized-managed-method-that-pushes-more-than-256-参数字节.aspx

最可能的问题是,由于方法签名太大,因此调用堆栈正在得到优化。

遇到了同样的问题,但是能够通过关闭调试器中的异常陷阱来解决。单击[调试] [例外],然后将例外设置为"用户未处理"。

通常我可以关闭此功能,但有时会派上用场。我只需要记住在完成后将其关闭。

查找具有许多参数的函数调用,并尝试减少数量直到调试返回。

这让我发疯。我尝试添加托管代码和本机代码。

这对我有用,我终于能够评估所有表达式:

  • 进入项目/属性
  • 选择"构建"选项卡,然后单击"高级..."。
  • 确保将"调试信息"设置为"完整"(并非仅限于pdb)
  • 调试项目-瞧!