【发布时间】:2015-02-25 15:03:21
【问题描述】:
今天我正在调试我的一些代码,它构建了一些表达式树,将它们编译为可调用的委托,然后在需要时调用它们。在执行此操作时,我遇到了一个 FatalExecutionEngineError 单步执行代码:
起初我有点震惊,因为我不知道我的表情可能有什么问题,它们看起来都很好。后来我发现这种情况只发生在以下情况:
Method A是一个静态方法,被调用并生成 ExpressionTree,它可能再次包含Expression.Call()到Method A。因此,在我为 ExpressionTree 编译 Lambda 之后,如果我在此方法中调用生成的委托(我们称之为Method B)可能会导致递归......(Method A->[Generated]Method B->Method A)。...这在我的场景中是完全可能的。如上所述,我正在调试这段代码,所以我在
Method A中设置了一个断点。Method A第一次被常规代码调用,断点照常命中。当Method B被调用时,断点再次命中,仍然一切正常。但是,当我跳过最后一行离开调试器的第二次调用时,
FatalExecutionEngineError就会出现。
如果我在没有调试的情况下运行代码,或者不进入对Method A 的递归调用,或者如果我不跨过方法的最后一行,则不会出现问题,并且我的表达式代码执行为预计。
我无法确定这是否是 VS-Debugger 或 .NET Framework 中的错误,或者我是否做了一些可怕的、可怕的错误,只有在调试相关行时才会出现。
这是一个非常简单的示例代码,您可以开箱即用。我正在使用 Visual Studio 2013 Prof Update 4 和 .NET 4.5.1。只需在DoSomething() 中设置一个断点,然后尝试单步执行到最后——如果可以的话;)
谁能确认一个错误,或者我的表达式格式不正确?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace ExpressionProblem
{
public class MainClass
{
public static void DoSomething(bool stop)
{
var method = typeof(MainClass).GetMethod(
"DoSomething",
BindingFlags.Public | BindingFlags.Static,
Type.DefaultBinder,
new Type[] { typeof(bool) },
null);
var expParam = Expression.Parameter(typeof(bool), "stop");
var expCall = Expression.Call(null, method, expParam);
var lambda = Expression.Lambda(expCall, expParam);
var @delegate = lambda.Compile();
if(!stop)
{
@delegate.DynamicInvoke(true);
}
}
public static void Main(string[] args)
{
DoSomething(false);
}
}
}
【问题讨论】:
-
哇!它工作/爆炸! :-)
-
我在使用 VS2012 或 VS2010 时得到了同样的结果,但只有在使用您描述的步骤时。如果我踏入
@delegate.DynamicInvoke,它只会爆炸,然后继续跨过(不让它运行)。 -
由于不调试时运行良好,估计是调试器的问题。
-
@Puer VS 2013 Update 4,测试了 32 位和 64 位应用程序
-
我也遇到过同样的问题。忽略并继续我的其余工作,因为当我们不通过它时它会起作用。如果只安装了 .Net 4.5(或更低版本),则不会发生这种情况。问题从.Net 4.5.1 开始是我发现的。
标签: c# debugging visual-studio-2013 expression expression-trees