释放COM对象有道?对象、COM

2023-09-03 04:27:38 作者:捏碎你的虚伪

有时,当我结束应用程序,它试图释放某些COM对象,我收到了调试器的警告:

Sometimes when I end the application and it tries to release some COM objects, I receive a warning in the debugger:

RaceOnRCWCleanUp 检测

如果我写一个类,它使用COM对象,做我需要实施的IDisposable 和呼叫 Marshal.FinalReleaseComObject 他们在 IDisposable.Dispose 来正确释放他们?

If I write a class which uses COM objects, do I need to implement IDisposable and call Marshal.FinalReleaseComObject on them in IDisposable.Dispose to properly release them?

如果处置不叫手动话,我还需要释放他们的终结或将GC自动释放呢?现在我电话的Dispose(假)在终结但我不知道如果这是正确的。

If Dispose is not called manually then, do I still need to release them in the finalizer or will the GC release them automatically? Now I call Dispose(false) in the finalizer but I wonder if this is correct.

我用同样的COM对象有一个事件处理程序,该班级听。显然,事件引发另一个线程,让我怎么正确地处理的时候类处理它,如果它被开除了?

The COM object I use also have an event handler which the class listens to. Apparently the event is raised on another thread, so how do I correctly handle it if it is fired when disposing the class?

推荐答案

根据使用不同的COM对象我的经验(在进程内或外的过程中)我建议每COM / .NET边界1对Marshal.ReleaseComObject交叉(如果比如你引用的COM对象,以便检索另一个COM参考)。

Based on my experience using different COM objects (in-process or out-of-process) I would suggest one Marshal.ReleaseComObject per one COM / .NET boundary crossing (if for instance you reference COM object in order to retrieve another COM reference).

我遇到了很多问题,只是因为我决定推迟COM互操作清理到GC。 另外请注意,我从来没有使用Marshal.ReleaseFinalComObject - 一些COM对象是单身,并没有与这些对象正常工作

I have run into many issues just because I decided to postpone COM interop cleanup to GC. Also please notice, I never use Marshal.ReleaseFinalComObject - some COM objects are singletons and it doesn't work well with such objects.

做任何事情在管理对象内终结器(或Dispose(假)从著名的IDisposable实现)是被禁止的。你不能依靠终结任何.NET对象的引用。你可以释放IntPtr的,但不是COM对象,因为它可能已经被清理干净。

Doing anything in managed objects inside finalizer (or Dispose(false) from the well-known IDisposable implementation) is forbidden. You must not rely on any .NET object reference in the finalizer. You can release IntPtr but not COM object as it could already be clean up.