为什么此代码抛出System.ExecutionEngineException

时间:2010-11-05 01:29:06

标签: c# exception managed-directx

背景 我正在使用DirectX 9.0托管库将3d点数组转换为2d屏幕坐标。为了速度,我使用UnsafeNativeMethods来完成所有的转换。

问题: 如果使用我的自定义行剪切功能,我的应用程序就会死掉而不会抛出任何异常,我花了一段时间才发现它正在抛出 uncatchable System.ExecutionEngineException。由于我的裁剪功能的最后两行,我已经缩小了它的范围。

List<Vector3> verticesAfterClipping = new List<Vector3>;
public unsafe void ClipLine(Line lineToClip)
{
    this.verticesAfterClipping.Clear();

    // Clipping algorithm happens here... (this is psuedo-code of what it does)
    foreach(Vertex in lineToClip.Vertices)
    {
        bool thisIsClipped =   // Set to whether this vertex is clipped
        bool lastWasClipped =  // Set to whether last vertex was clipped

        if(thisIsClipped == false && lastWasClipped == true)
        {
            verticesAfterClipping.Add( /* intersection on clipping plane */ );
            verticesAfterClipping.Add( /* thisVertex */ );
        }
        else if (thisIsClipped == false && lastWasClipped == false)
        {
            verticesAfterClipping.Add( /* thisVertex */ );
        }
        else if (thisIsClipped == true && lastWasClipped == false)
        {
            verticesAfterClipping.Add(/* intersection on clipping plane */);
        }
    }

    // THIS IS WHERE BAD THINGS HAPPEN
    lineToClip.Vertices = new Vertex[verticesAfterClipping.Count];
    verticesAfterClipping.CopyTo(lineToClip.Vertices, 0);
}

verticesAfterClipping列表复制到lineToClip顶点后,lineToClip对象将传递给UnsafeNativeMethod,后者将这些顶点转换为2d顶点。从我在调试模式中逐步完成它时所看到的一切,它完全正常,直到它完全消失。

我根本无法弄清楚出了什么问题。任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:13)

实际上可能不会在抛出异常的行中发生此问题。这可能只是之前发生的事情的症状。

当CLR 检测到某些内容出现严重错误时,会引发System.ExecutionEngineException异常。这可能在问题发生后相当长的一段时间内发生。这是因为异常通常是内部数据结构损坏的结果--CLR发现某些东西已进入一种无意义的状态。它抛出了一个无法捕获的异常,因为它不安全。

因此,您可能在系统中某些完全不相关的部分中存在一些破坏某些内容的代码,但这只有在这段特定代码运行时才会变得明显。您展示的代码可能很好。 (它也可能不是......我没有看到任何明显的错误,但后来我不知道DX 9托管库。例如,我无法看到此方法的哪个功能需要unsafe关键字。 )

不幸的是,这意味着你需要开始更宽一点的网络。几乎任何使用不安全代码或COM互操作的东西都可能是可疑的。遗憾的是,这将是一个漫长而乏味的过程。您可能采用的一种方法是尝试逐步简化程序:可以说明问题的最小代码是什么? (例如,如果你把你在那里展示的代码放到一个除了对该方法最简单的调用之外什么都没有的应用程序中,它是否仍会失败?)

答案 1 :(得分:1)

我对不同的库有同样的问题。在我的情况下,所有开始很久以前因为我必须在64位环境中运行32位.net应用程序。这给我带来了很多麻烦,架构之间的兼容性,或.NET框架的CLR之间的兼容性也可能是你的问题。

PS:现在我知道我的麻烦是什么但不知道 在哪里。

答案 2 :(得分:0)

我有两个类处理数据库中的特定表

StorageManager-一个类,该类具有处理与数据库直接交互的方法

Controller-一个具有处理api调用方法的类

当要在表中创建新条目时,我检查子表中是否存在某些可能的值。

我编写了这些方法来检查错误的类中是否存在/重复的对象,最终导致我为我抛出了executeengineException。

移动这些方法,使它们与正确的数据库上下文一起使用似乎可以解决我的问题。