“不能评估expression式,因为当前方法的代码已经优化了”是什么意思?
我写了一些recursion很多的代码,需要很长时间才能完成。 每当我“暂停”运行,看看发生了什么,我得到:
由于当前方法的代码已经过优化,因此无法评估expression式。
我想我明白这意味着什么。 然而,让我感到困惑的是,在我执行完一步之后,代码不再被“优化”,我可以看看我的variables。 这是怎么发生的? 代码如何在优化和非优化代码之间来回切换?
debugging器使用FuncEval来允许你“查看”variables。 FuncEval要求线程在GarbageCollector安全点的托pipe代码中停止。 手动“暂停”IDE中的运行会导致所有线程尽快停止。 你的高度recursion代码往往会停在一个不安全的地方。 因此,debugging器无法评估expression式。
按F10将移到下一个Funceval安全点,并启用function评估。
有关更多信息,请查看FuncEval的规则 。
当Debug.Break()行位于callstack的顶部时,您无法评估expression式。 这是因为这条线是优化的。 按F10移动到下一行 – 有效的一行代码 – 手表将工作。
您可能试图在发布模式而不是debugging模式下debugging您的应用程序,或者在编译设置中打开优化。
当代码被优化编译时,某些variables在函数中不再使用时就会被抛弃,这就是为什么你会得到这个消息。 在优化禁用的debugging模式下,您不应该得到这个错误。
这让我疯狂。 我尝试使用托pipe代码和本机代码进行连接 – 不行。
这对我有用,我终于能够评估所有expression式:
- 进入项目/属性
- select生成选项卡,然后单击高级…
- 确保debugging信息设置为“完整”(而不是仅限pdb)
- debugging你的项目 – 瞧!
寻找一个带有许多参数的函数调用,并尝试减less数量直到debugging返回。
以下为我工作,谢谢@Vin。
我在使用VS 2015时遇到了这个问题。我的解决scheme是:configuration(Debug)被选中。 我通过取消select项目属性下的Optimize Code
属性来解决这个问题。
项目(右键单击)=>属性=>构build(选项卡)=>取消选中优化代码
来自微软的朋友的朋友发送了这个: 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-更比256参数字节-的.aspx
最可能的问题是您的调用堆栈得到优化,因为您的方法签名太大。
有相同的问题,但能够通过closuresdebugging器中的exception陷阱来解决它。 点击[debugging] [例外],将例外设置为“用户未处理”。
通常我有这个,但偶尔会派上用场。 我只需要记得在完成之后closures它。
我在使用VS 2010时遇到了这个问题。我的解决schemeconfigurationselect了(debugging)。 我通过取消select项目属性下的优化代码属性来解决这个问题。 项目(右键单击)=>属性=>构build(选项卡)=>取消选中优化代码
确保你没有这样的事情
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
在你的AssemblyInfo
在我的情况下,我有两个项目在我的解决scheme,并运行一个不是启动项目的项目。 当我将其更改为启动项目时,debugging开始重新开始。
希望它可以帮助别人。
评定:
在.NET中,“函数评估(funceval)”是CLR在debugging对象停止某处时注入一些任意调用的能力。 Funceval负责debugging器select的线程来执行请求的方法。 一旦funceval完成,它会触发一个debugging事件。 从技术上讲,CLR已经定义了debugging器发布funceval的方法。
CLR只允许在GC安全点(即线程不会阻塞GC)和Funceval安全(FESafe)点(即CLR实际上可以对funceval进行劫持)的线程上启动funceval。 因此,CLR的可能场景,一个线程必须是:
-
停在托pipe代码(和一个GC安全点):这意味着我们不能在本机代码中做一个funceval。 由于本机代码不在CLR的控制范围之内,因此无法设置funceval。
-
在第一次机会或未处理的pipe理exception(和GC安全点)时停止:即在例外情况下,尽可能多地检查以确定发生exception的原因。 (例如:debugging器可能会尝试评估并查看引发exception的Message属性。)
总体而言,在托pipe代码中停止的常见方法包括在断点处停止,执行Debugger.Break调用,拦截exception或在线程启动时停止。 这有助于评估方法和expression式。
可能的解决scheme:根据评估,如果线程不在FESafe和GCSafe点,CLR将无法劫持线程来启动funceval。 一般来说,以下有助于确保funceval在预期时启动:
步骤1:
确保你没有试图debugging“Release”版本。 发布完全优化,从而导致在讨论中的错误。 通过使用标准工具栏或configurationpipe理器,您可以在debugging和发布之间切换。
第2步:
如果仍然出现错误,则可能会将debugging选项设置为优化。 validation并取消选中项目“属性”下的“优化代码”属性:
右键单击项目select选项“属性”转到“生成”选项卡取消选中“优化代码”checkbox
步骤#3:
如果仍然出现错误,则debugging信息模式可能不正确。 在“高级构build设置”下validation并将其设置为“完整”:
右键单击项目select选项“属性”转到“生成”选项卡单击“高级”button将“debugging信息”设置为“完整”
步骤4:
如果您仍然遇到问题,请尝试以下操作:
做一个“干净”,然后“重build”你的解决scheme文件在debugging时:进入模块窗口(菜单 – >debugging – > Windows – >模块)在加载模块的列表中find你的程序集。 检查已加载程序集列出的path是否是您期望的path检查文件的已修改时间戳以确认程序集实际上已重build检查加载的模块是否已优化
结论:
这不是一个错误,而是基于某些设置的信息,并根据.NET运行时的工作原理devise。
在我的情况下,我是在发布模式的人,我改变debugging一切工作
我有一个类似的问题,当我在debugging模式下构build解决scheme并取代执行path中的pdb文件时,它得到解决。
我相信你所看到的是优化的结果 – 有时候一个variables会被重用 – 尤其是那些在栈上创build的variables。 例如,假设你有一个使用两个(本地)整数的方法。 第一个整数是在方法的开始处声明的,并且仅用作循环的计数器。 在循环完成后使用第二个整数,并存储稍后写入文件的计算结果。 在这种情况下,优化器可以决定重用你的第一个整数,保存第二个整数所需的代码。 当您尝试尽早查看第二个整数时,您会收到有关“无法评估expression式”的消息。 虽然我无法解释确切的情况,但是稍后优化器可能会将第二个整数的值转换为单独的堆栈项,导致您可以从debugging器访问该值。