Почему этот код вызывает System.ExecutionEngineException

Справочная информация. Я использую управляемые библиотеки DirectX 9.0 для преобразования массивов трехмерных точек в координаты экрана 2d. Для скорости я использую UnsafeNativeMethods для выполнения всех преобразований.

Проблема. Если моя пользовательская функция отсечения строки используется, мое приложение умирает без каких-либо исключений, мне потребовалось некоторое время, чтобы понять, что он бросает непонятное System.ExecutionEngineException . Я сузил его, чтобы произойти из-за последних двух строк моей функции отсечения.

 List verticesAfterClipping = new List; 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 вершины. Из всего, что я вижу, когда я перехожу через него в режиме отладки, он работает полностью нормально, пока он просто не умрет.

Я просто не могу понять, что не так. Любая помощь приветствуется.

На самом деле проблема не возникает в строке, которая генерирует исключение. Это может быть лишь признаком того, что произошло раньше.

Исключение System.ExecutionEngineException когда CLR обнаруживает , что что-то пошло ужасно неправильно. Это может произойти через некоторое время после возникновения проблемы. Это связано с тем, что исключение обычно является результатом коррупции внутренних структур данных – CLR обнаруживает, что что-то попало в состояние, которое не имеет смысла. Он выдает исключение, исключающее, так как это не безопасно.

Таким образом, у вас может быть какой-то код в какой-то совершенно несвязанной части системы, которая что-то развращает, но это становится очевидным только при выполнении этой конкретной части кода. Код, который вы показали, может быть очень хорошим. (Это также может быть не так … Я не вижу ничего очевидного неправильно, но тогда я не знаю хорошо управляемых библиотек DX 9. Я не вижу, какая функция этого метода требует, например, ключевого слова unsafe. )

К сожалению, это означает, что вам нужно начать отливать сеть немного шире. Практически все, что использует либо небезопасный код, либо COM-взаимодействие потенциально подозрительно. К сожалению, это будет долгий и утомительный процесс. Один из способов, по которым вы можете приблизиться к нему, – попытаться постепенно упростить программу: какой самый маленький fragment кода может показать проблему? (Например, если вы поместили код, который вы показали там, в приложение, которое не содержит ничего другого, кроме простейшего возможного вызова этого метода, все равно не работает?)

У меня такая же проблема с разными библиотеками. В моем случае все началось задолго до того, потому что я должен был запустить 32-разрядное приложение .net в 64-битной среде. Ну, это вызывает у меня много проблем, совместимость между архитектурами или между CLR вашей платформы .NET может быть и вашей проблемой.

PS: Теперь я знаю, в чем моя проблема, но понятия не имею, где это.

У меня есть два classа, которые относятся к определенной таблице в моей базе данных

StorageManager – class, который имеет методы, которые обрабатывают прямые взаимодействия с базой данных

Controller – class, который имеет методы обработки вызовов api

Когда новая запись в таблице будет создана, я проверю дочерние таблицы на определенные значения, которые могут уже существовать.

Я написал эти методы, чтобы проверить наличие ранее существовавших / дубликатов в неправильном classе, что в итоге привело к тому, что для меня возникло исключение executingengineexception.

Перемещение методов, чтобы они жили с правильным контекстом базы данных, казалось, исправило это для меня.