51

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

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

我想我明白这意味着什么。然而,令我困惑的是,在我点击 step 之后,代码不再“优化”,我可以查看我的变量。这是怎么发生的?代码如何在优化代码和非优化代码之间来回翻转?

4

15 回答 15

46

虽然 Debug.Break() 行位于调用堆栈的顶部,但您无法评估表达式。那是因为那条线是优化的。按 F10 移动到下一行 - 有效的代码行 - 手表将工作。

于 2008-12-12T09:46:40.347 回答
30

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

按 F10 将移动到下一个功能安全点并启用功能评估。

有关详细信息,请查看FuncEval 的规则

于 2008-09-25T06:00:42.050 回答
28

您可能正在尝试在发布模式而不是调试模式下调试您的应用程序,或者您在编译设置中打开了优化。

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

于 2008-09-25T05:46:43.940 回答
7

这让我发疯了。我尝试使用托管和本机代码附加 - 不行。

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

  • 进入项目/属性
  • 选择构建选项卡并单击高级...
  • 确保调试信息设置为“完整”(不是 pdb-only)
  • 调试您的项目 - 瞧!
于 2010-08-03T15:43:21.233 回答
7

以下对我有用,谢谢@Vin。

我在使用 VS 2015 时遇到了这个问题。我的解决方案:选择了配置(调试)。我通过取消选中Optimize Code项目属性下的属性解决了这个问题。

项目(右键单击)=> 属性 => 构建(选项卡)=> 取消选中优化代码

于 2016-04-26T16:35:30.407 回答
3

确保你没有类似的东西

[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]

在你的AssemblyInfo

于 2016-10-06T13:39:09.177 回答
2

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

于 2009-11-14T02:34:27.097 回答
1

微软朋友的朋友发送了这个:http: //blogs.msdn.com/rmbyers/archive/2008/08/16/Func_2D00_eval-can-fail-while-stopped-in-a-non_2D00_optimized-managed-method-that -push-more-than-256-argument-bytes-.aspx

最可能的问题是您的调用堆栈正在优化,因为您的方法签名太大。

于 2009-03-09T22:11:36.953 回答
1

有同样的问题,但能够通过关闭调试器中的异常捕获来解决它。单击[Debug][Exceptions]并将异常设置为“User-unhandled”。

通常我会关闭它,但它偶尔会派上用场。我只需要记住在完成后将其关闭。

于 2009-03-10T14:44:08.847 回答
1

我在使用 VS 2010 时遇到了这个问题。我的解决方案配置已选择(调试)。我通过取消选中项目属性下的优化代码属性解决了这个问题。项目(右键单击)=> 属性 => 构建(选项卡)=> 取消选中优化代码

于 2011-05-02T21:42:04.370 回答
0

就我而言,我的解决方案中有 2 个项目,并且正在运行一个不是启动项目的项目。当我将其更改为启动项目时,调试再次开始工作。

希望它可以帮助某人。

于 2015-03-13T22:00:50.700 回答
0

评估:

在 .NET 中,“函数评估 (funceval)”是 CLR 在调试对象在某处停止时注入一些任意调用的能力。Funceval 负责调试器选择的线程来执行请求的方法。一旦 funceval 完成,它会触发一个调试事件。从技术上讲,CLR 已经定义了调试器发出 funceval 的方法。

CLR 只允许在那些处于 GC 安全点(即线程不会阻塞 GC)和功能安全 (FESafe) 点(即 CLR 实际上可以为 funceval 劫持)的线程上启动 funceval。因此,对于 CLR 的可能场景,线程必须是:

  1. 在托管代码中停止(并且在 GC 安全点):这意味着我们不能在本机代码中执行 funceval。由于本机代码不在 CLR 的控制范围内,因此无法设置 funceval。

  2. 在第一次机会或未处理的托管异常时停止(并且在 GC 安全点):即在异常时,尽可能多地检查以确定该异常发生的原因。(例如:调试器可能会尝试评估并查看引发异常的 Message 属性。)

总体而言,在托管代码中停止的常见方法包括在断点、步骤、Debugger.Break 调用、拦截异常或线程启动处停止。这有助于评估方法和表达式。

可能的解决方案:根据评估,如果线程不在FESafe和GCSafe点,CLR将无法劫持线程启动funceval。通常,以下有助于确保 funceval 在预期时启动:

第1步:

确保您没有尝试调试“发布”版本。发布是完全优化的,因此会导致讨论中的错误。通过使用标准工具栏或配置管理器,您可以在调试和发布之间切换。

第2步:

如果您仍然收到错误,则可能会设置 Debug 选项以进行优化。验证并取消选中项目“属性”下的“优化代码”属性:

右键单击项目选择选项“属性”转到“构建”选项卡取消选中“优化代码”复选框</p>

第 3 步:

如果您仍然收到错误,则调试信息模式可能不正确。在“高级构建设置”下验证并将其设置为“完整”:

右键单击项目选择选项“属性”转到“构建”选项卡单击“高级”按钮将“调试信息”设置为“完整”</p>

第4步:

如果您仍然遇到问题,请尝试以下操作:

对解决方案文件进行“清理”然后“重建” 调试时:转到模块窗口(VS 菜单 -> 调试 -> Windows -> 模块)在已加载模块列表中找到您的程序集。检查针对加载的程序集列出的路径是您期望的路径检查文件的修改时间戳以确认程序集实际上已重建检查加载的模块是否已优化

结论:

这不是错误,而是基于某些设置的信息,并且是根据 .NET 运行时的工作方式设计的。

于 2015-10-28T11:43:38.793 回答
0

在我的情况下,我处于发布模式,我更改为调试它一切正常

于 2016-03-20T03:35:01.673 回答
0

我有一个类似的问题,当我在调试模式下构建解决方案并替换执行路径中的 pdb 文件时,它得到了解决。

于 2017-11-08T09:07:58.487 回答
-1

我相信你所看到的是优化的结果——有时一个变量会被重用——尤其是那些在堆栈上创建的变量。例如,假设您有一个使用两个(本地)整数的方法。第一个整数在方法的开头声明,并且仅用作循环的计数器。您的第二个整数在循环完成后使用,它存储稍后写入文件的计算结果。在这种情况下,优化器可能决定重用你的第一个整数,保存第二个整数所需的代码。当您尝试尽早查看第二个整数时,您会收到有关“无法评估表达式”的消息。虽然无法说明具体情况,

于 2008-09-25T06:30:59.280 回答