c# - 将操作放入 lambda 会导致 C# 中的 SystemAccessViolation
问题描述
我很困惑为什么SystemAccessViolation
当我取消注释调用该操作的行时会出现以下代码。
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、.NET Framework 4.8)。
只要在 lambda 内部调用的操作被注释掉,上面的代码就可以正常工作。
对于不熟悉 OpenGL 的任何人,GL.DebugMessageCallback()
最有可能会做一些原生的东西。正因为如此,我不知道这是否意味着 C# 失去了对动作的跟踪并尝试做不应该做的事情,或者 OpenGL 正在做的事情与我编写的代码不匹配。GC是否有可能已经清理action
并试图调用它?我猜在这一点上。
action()
当未注释时,我无法在其中放置断点,断点不会被触发。action()
但是,当完全注释掉时,我可以使断点工作。调用的顺序与它是在 lambda 的顶部还是底部无关。
解决方案
推荐阅读
- javascript - 如何从 chrome 扩展访问 Django 服务(托管在另一个 IP 上)
- html - HTML 使用 CSS 更改文本的字体颜色(Mac OS、Chrome)
- python - 在python中捕获字段的变化
- .net - 批量请求中的 Odata 相对 url
- animation - 在 React Native Animated 中使用 useNativeDriver 时出错
- php - 坚持在网站上开发一个 cooment 盒子
- angular - 可以在可排序的primeng表中更改列的宽度吗?
- regex - 在正则表达式中使用静态字符串一次,同时使用两种模式 OR
- storage - 如何以 URL 直接访问 Ceph 上的文件
- oracle - Oracle SQL - 使用 if 子句驱动变量