Я с большим колебанием задаю этот вопрос, потому что я знаю, что всякий раз, когда вы думаете, что нашли ошибку в чем-то вроде .NET Framework, скорее всего, вы просто делаете что-то не так. Тем не менее, я действительно не могу понять, что вызвало мою текущую ситуацию.
Я создаю трассировщик лучей в C #, и в особом случае оператор return метода никогда не вызывается. Странно то, что совершенно не связанные вещи влияют на это поведение.
Вы можете увидеть оскорбительный метод здесь:
public Primitive FindNearest(ref float distance, Ray ray, ref RayCollision collisionResult)
{
if (!_initialized) InitUnit();
Primitive hitPrimitive = null;
//Search the planes
foreach (var plane in RenderEngine.Scene.Planes)
{
RayCollision collision = plane.Intersect(ray, ref distance);
if (collision != RayCollision.Miss)
{
hitPrimitive = plane;
collisionResult = collision;
}
}
if (_spatialStructure == null)
{
//Default collision detection
foreach (Primitive primitive in _primitives)
{
//RayCollision collision = primitive.Intersect(ray, ref distance);
//if (collision != RayCollision.Miss)
//{
// hitPrimitive = primitive;
// collisionResult = collision;
//}
}
}
else
{
//hitPrimitive = _spatialStructure.GetClosestIntersectionPrimitive(ray, ref distance, out collisionResult);
//Console.WriteLine("Was here");
RayCollision collision;
Primitive prim = _spatialStructure.GetClosestIntersectionPrimitive(ray, ref distance, out collision);
if (collision != RayCollision.Miss)
{
hitPrimitive = prim;
collisionResult = collision;
}
}
return hitPrimitive;
}
Только один поток вызывает этот метод, и при каждом вызове выполняется оператор Console.Writeline, но оператор возврата никогда не достигается. Метод вызывается сотни раз, и при каждом вызове «был здесь» выводится на консоль.
Если я закомментирую второй foreach (тот, в котором все комментарии), оператор return будет выполнен как обычно, но закомментированный код никогда не будет достигнут. Другие типы реструктуризации кода также могут заставить его работать как задумано, но опять же не по любой причине, которая имеет для меня смысл.
Это поведение больше похоже на проблему повреждения памяти, с которой можно столкнуться в C, поэтому у меня нет никаких подсказок относительно того, что могло вызвать это - кроме ошибки в .NET, то есть.
Кстати, версия .NET, которую я использую, - 3.5 sp1.
Обновление 3
В итоге оказалось, что точка останова была съедена, потому что я был в режиме освобождения. Я думаю, вы узнаете что-то новое каждый день.
Обновление 2
Кажется, я был настолько сосредоточен на странном поведении, что не увидел ошибку в своем коде. Я изменил код, чтобы отразить это, но у меня все еще есть проблема с тем, чтобы никогда не вызывать точку останова в операторе return - что указывает на ошибку в visual studio (2008), а не на .net. Но мой код теперь работает, и я думаю, мне придется с этим согласиться.
Обновление
Здесь приведена разборка для входа в функцию Console.Writeline, которая является последним известным местом перед исчезновением потока управления (нет исходного кода, доступного для входа). Я не могу читать ассемблер, поэтому я не знаю, что это значит, но для кого-то это может иметь смысл.
0000002a mov r11,qword ptr [rbx+20h]
0000002e mov rax,qword ptr [r11]
00000031 mov rdx,rdi
00000034 mov rcx,r11
00000037 call qword ptr [rax+000001A0h]
0000003d lea rdx,[rbp+8]
00000041 mov rcx,rbx
00000044 call FFFFFFFFFFF0C410
00000049 jmp 0000000000000050
0000004b jmp 0000000000000050
0000004d nop dword ptr [rax]
00000050 lea rsp,[rbp+10h]
00000054 pop rdi
00000055 pop rbp
00000056 pop rbx
00000057 rep ret
00000059 push rbx
0000005a push rbp
0000005b push rdi
0000005c sub rsp,30h
00000060 mov rbp,qword ptr [rcx+20h]
00000064 mov qword ptr [rsp+20h],rbp
00000069 lea rbp,[rbp+20h]
0000006d lea rdx,[rbp+8]
00000071 mov rcx,qword ptr [rbp+30h]
00000075 call FFFFFFFFFF56F3E9
0000007a nop
0000007b add rsp,30h
0000007f pop rdi
00000080 pop rbp
00000081 pop rbx
00000082 rep ret