C# 在lambda中放置操作会导致C中的SystemAccessViolation#
我不明白为什么在我取消对调用操作的行的注释时,下面的代码会发生C# 在lambda中放置操作会导致C中的SystemAccessViolation#,c#,opentk,C#,Opentk,我不明白为什么在我取消对调用操作的行的注释时,下面的代码会发生systemaccessinvalition GL.Enable(EnableCap.DebugOutput); GL.Enable(EnableCap.DebugOutputSynchronous); Action action = () => { Console.WriteLine("Hello"); }; DebugProc debugProc = (source, type, id, severity, length
systemaccessinvalition
GL.Enable(EnableCap.DebugOutput);
GL.Enable(EnableCap.DebugOutputSynchronous);
Action action = () => { Console.WriteLine("Hello"); };
DebugProc debugProc = (source, type, id, severity, length, message, userParam) =>
{
string msg = Marshal.PtrToStringAnsi(message, length);
Console.WriteLine("Debug message: " + msg);
// Uncommenting this causes a SystemAccessViolation.
//action.Invoke();
};
GL.DebugMessageCallback(debugProc, IntPtr.Zero);
当我在非调试模式下运行它时,我得到:
Unhandled Exception: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
at OpenTK.Graphics.OpenGL4.GL.BufferData[T2](BufferTarget target, Int32 size, T2[] data, BufferUsageHint usage)
当我通过调试运行它时,我得到:
Unexpected exception: Object reference not set to an instance of an object.
Stack trace:
at System.StubHelpers.StubHelpers.CheckCollectedDelegateMDA(IntPtr pEntryThunk)
at OpenTK.Graphics.OpenGL4.GL.BufferData[T2](BufferTarget target, Int32 size, T2[] data, BufferUsageHint usage)
我也不确定我的问题是否应该向OpenTK报告,或者我是否在C#(使用C#8、.NETFramework4.8)中出错 只要在lambda中调用操作并注释掉,上述代码就可以正常工作 对于任何不熟悉OpenGL的人来说,
GL.DebugMessageCallback()
很可能会做一些本机工作。正因为如此,我不知道这是否意味着C#失去了对动作的跟踪,并尝试做一些它不应该做的事情,或者OpenGL正在做的某些事情对我编写的代码不好。GC是否可能已经清理了操作
,并试图调用它?不过,在这一点上,我是在猜测
当action()
未注释时,我无法在其内部放置断点,断点不会被触发。但是,当action()
被完全注释掉时,我可以使断点工作。调用的顺序与它是在lambda的顶部还是底部无关。“是否有可能GC已经清理了该操作并试图调用它?”--是的,当然有可能。在调试器下运行时,堆栈跟踪中存在CheckCollectedDelegateMDA()
,这实际上可以确定发生了什么。请参阅标记的副本。有关建议,请参见。在您的示例中,添加GC.KeepAlive(操作)代码>在调用GL.DebugMessageCallback
后应该修复它,假设这是您使用debugProc
的唯一地方。您是否遇到了可能的问题?“GC是否已经清理了该操作并试图调用它?”--是的,当然可能。在调试器下运行时,堆栈跟踪中存在CheckCollectedDelegateMDA()
,这实际上可以确定发生了什么。请参阅标记的副本。有关建议,请参见。在您的示例中,添加GC.KeepAlive(操作)在GL.DebugMessageCallback
调用之后,code>应该会修复它,假设这是您唯一使用debugProc
的地方。您可能遇到了什么问题?