3

为了学习 C# 本机互操作,我一直在研究 OpenGL 包装器。OpenGL API 本身是一个绑定到特定线程的状态机。当一个包含原生资源的对象被垃圾回收时,终结器在 GC 线程中运行,不能直接释放资源。

我目前拥有的解决方法是在上下文对象中有一个列表,对象将其资源添加到该列表中,并在绘制循环中的安全点进行迭代并释放它们。

但是,这样做的问题是,如果 GC 在迭代该列表时收集,则 foreach 将失败,因为该集合已被修改。我不能只在列表周围放置一个互斥锁,因为在大多数实现中 GC 是停止世界的,如果绘制循环已锁定它,它永远不会完成迭代并再次解锁它。

通常,MTBF 大约是两个小时的游戏时间,但如果有意以每秒几千个对象进行压力测试,它只会在几秒钟内发生。

这里最好的方法是什么?

4

4 回答 4

1

然后,您将咬紧牙关,停止依赖 GC 为您进行资源管理。您将不得不让您的资产管理器有一个明确的函数来删除它分配的对象,而不是依赖于资产管理器的终结器函数。而且您将不得不在代码中的特定位置调用该函数。

仅仅因为你GC 并不意味着它是最好的或唯一的解决方案。

于 2013-05-31T11:38:04.540 回答
1

发问者写道/陈述:

OpenGL API 本身是一个绑定到特定线程的状态机。

这是错误的!

OpenGL 上下文一次只能在一个线程中处于活动状态。这并不意味着不能从不同的线程使用上下文。本质上,OpenGL 上下文是一个互斥资源(提示:Mutex),{wgl,glX}MakeCurrent(DC, RC)在线程中使用它()之前要绑定它,并且在完成所需的任何上下文之后,您可以从当前线程中取消绑定 OpenGL 上下文({wgl,glX}MakeCurrent(NULL, NULL)) .

于 2013-05-31T12:57:42.697 回答
0

您可以随时使用该fixed语句。

见这里http://msdn.microsoft.com/en-us/library/f58wzh21%28VS.80%29.aspx

于 2013-05-31T10:19:44.380 回答
0

听起来您真正的问题是您的对象带有暴露其资源的终结器。如果你打算直接使用资源,你应该在没有终结器的对象中创建和存储它们,并确保你执行必要的规则来防止资源泄漏。

于 2014-01-14T23:10:55.180 回答