C++ cli 封装DirectSound接口的托管类是否应该IDisposable?

C++ cli 封装DirectSound接口的托管类是否应该IDisposable?,c++-cli,idisposable,directsound,C++ Cli,Idisposable,Directsound,我正在围绕DirectSound编写一个托管包装。(这是一个简单的部分包装,解决了我的具体问题,仅此而已。不要告诉我NAudio或其他任何东西。)包装IDirectSound8的托管类是否应该IDisposable?为什么?关于IDirectSoundBuffer8的同样问题。从技术上讲:是的。实际上:不是。IDirectSound8是一个COM接口,它们非常方便地包装在带有互操作库的.NET中。RCW。RCW管理基础COM coclass对象上的引用计数。RCW不实现IDisposable,即

我正在围绕DirectSound编写一个托管包装。(这是一个简单的部分包装,解决了我的具体问题,仅此而已。不要告诉我NAudio或其他任何东西。)包装IDirectSound8的托管类是否应该IDisposable?为什么?关于IDirectSoundBuffer8的同样问题。

从技术上讲:是的。实际上:不是。IDirectSound8是一个COM接口,它们非常方便地包装在带有互操作库的.NET中。RCW。RCW管理基础COM coclass对象上的引用计数。RCW不实现IDisposable,即使它非常依赖于非托管资源

之所以没有,是因为几乎不可能正确实现IDisposable。COM类实现多个接口,创建一个接口会增加引用计数。在dispose安全之前,您必须100%确保所有这些接口指针不再使用。这很难做到,这些指针是以意外的方式创建的。与使用其中一个接口的索引属性类似,中间接口指针在代码中永远不可见

这不是一个真正的问题,垃圾收集器负责引用计数,终结器完成任务。只是释放对象需要更长的时间。标准GC行为。不幸的是,进程外COM服务器具有明显的副作用,当代码停止使用接口时,如果进程没有从TaskMgr进程列表中消失,程序员往往会感到恼火。这里和论坛上有很多“Excel/Word不退出”的问题

如果仍要实现它,则可以通过在Dispose()实现中调用Marshal.finalEleaseComObject()来实现。只需注意显著增加的失败风险,错误的呼叫会导致非常难以诊断的失败。这与在本机代码中删除对象并仍然有指向它的指针没什么不同。如果它实际上是一个“重”对象,必须立即释放,那么GC.Collect()+GC.WaitForPendingFinalizers()也可以完成任务,而出错的风险要小得多。当然有副作用