要学习C#native interop,我一直在研究OpenGL包装器。 OpenGL API本身是一个绑定到特定线程的状态机。当包含本机资源的对象被垃圾收集时,终结器在GC线程中运行,并且不能直接释放资源。
我目前的解决方法是在上下文对象中有一个列表,对象将它们的资源添加到它并在它迭代的绘制循环中的安全点并释放它们。
然而,问题在于,如果GC在迭代该列表时收集,则foreach会因为集合已被修改而失败。我不能只是在列表中放置一个互斥体,因为GC在大多数实现中是停止世界的,如果绘制循环锁定了它,它就永远不会完成迭代并再次解锁。
通常情况下,MTBF大约需要两个小时的游戏时间,但如果故意用每秒几千个物体进行压力测试,则只需几秒钟即可完成。
这里最好的方法是什么?
答案 0 :(得分:1)
然后你会咬紧牙关,不再依赖GC来为你做资源管理。您将不得不让您的资产管理器具有删除其分配的对象的显式功能,而不是依赖资产管理器的终结器功能。而且您将不得不在代码中的特定位置调用该函数。
仅仅因为你拥有 GC并不意味着它是最佳或唯一的解决方案。
答案 1 :(得分:1)
提问者写道/声明:
OpenGL API本身是一个绑定到特定线程的状态机。
错误!
OpenGL上下文一次只能在一个线程中激活。这并不意味着,不能从不同的线程使用上下文。本质上,OpenGL上下文是一个互斥的资源(提示:Mutex),它在一个线程中使用它之前被绑定({wgl,glX}MakeCurrent(DC, RC)
),在完成所需的上下文之后,你从当前线程解除绑定OpenGL上下文({wgl,glX}MakeCurrent(NULL, NULL)
)。
答案 2 :(得分:0)
您始终可以使用fixed
声明。
请参阅此处http://msdn.microsoft.com/en-us/library/f58wzh21%28VS.80%29.aspx
答案 3 :(得分:0)
听起来好像你的真正问题是你有终结器的对象暴露他们的资源。如果您要直接使用资源,则应该在没有终结器的情况下创建并存储它们,并确保您运用必要的规则来防止资源泄漏。