跟踪释放C#中的COM对象

5

我有一个c#的com类,被未托管的代码使用。我可以调试它,但是我无法知道何时对象被释放。如果它是用c++实现的,在析构函数中会被调用,在c#中则会被释放到GC中。是否有任何方法来跟踪这一时刻呢? 提前感谢。


你在寻找一个终结器吗? - SLaks
只是好奇,你可以在这种情况下使用 C# 的 析构函数 吗? - Bala R
这里没有令人愉快的答案。你的[ComVisible]类实例只是一个普通的.NET对象。它通过CCW中的引用保持活动状态。最后的Release()调用会销毁CCW,但对你的.NET对象没有任何影响。直到像正常情况下一样被垃圾回收。你需要调试本机代码。问题无疑就在那里。 - Hans Passant
1个回答

1

维护非托管资源的托管类型应该实现IDisposable接口。这告诉您代码的使用者,当他们完成对对象的使用时(即在可能的情况下将它们包装在using块中),他们需要调用Dispose()

IDisposable的适当实现将在其终结器中释放本机资源,但客户端可以更早地调用Dispose()以确定性地释放非托管资源。无论哪种方式,都可以避免泄漏,但尽快调用Dispose()是更好的选择。

这里有一个SO问题详细介绍了这个过程。


问题在于我无法控制非托管代码。没有必要的清理工作不能由GC完成。我只是想知道我的对象的预期生命周期。 - user629926
如果您无法控制本地代码,那么我不理解问题所在。托管代码无法清理本地代码,除非本地代码定义了一个接口来进行清理。GC负责管理包装器是无关紧要的;它不能神奇地清理本地内容。您必须通过实现IDisposable并调用一些函数来释放本地资源来自己完成这个过程。 - Ed S.
我没有任何本地资源可供清理,只想知道何时实现托管包装器。 - user629926
那你为什么还要提COM呢?我有点困惑。托管资源会在垃圾回收器决定释放它们时被释放。关于垃圾回收器的工作原理,有很多资源可供参考。你为什么需要知道这些呢?你可以实现一个终结器,但从你提出这个问题的方式来看,我建议你在这之前先学习一下相关知识。 - Ed S.
本地代码以不确定的方式使用我的类。有时它会在整个应用程序生命周期内使用相同的对象。有时它只是停止从一个方法调用,然后实例化新的具有相同值的对象等等,因此我想知道在实例化新对象之前是否释放了我的对象... - user629926

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接