我有一个使用.NET包装器的类用于COM对象,而且它给了我臭名昭着的RCW错误,所以在我的调查中我发现如果我从这个类的终结器中取出Dispose()方法它会修复RCW错误,所以有些东西是错误的,例如对象被处理掉了,但注册的事件仍在闲逛...但是只是删除Dispose()不能成为答案,因为那时谁将释放内存? (我运行了一个内存分析器并确认只是删除Dispose方法会导致20MB的额外非托管内存)
所以我使用Dispose模型的方式应该是错的..这就是我所拥有的:
private MyCOMobject theCOMobject = null;
static SuppressFieldCntrlr()
{
new SomeCalss();
}
~SuppressFieldCntrlr()
{
Dispose(false);
}
private bool disposed = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
theCOMobject.Dispose();
}
MethodFoo(false);
disposed = true;
}
}
答案 0 :(得分:3)
对于COM对象,您需要调用Marshal.ReleaseComObject
。 Marshal类位于命名空间System.Runtime.InteropServices
。
更多信息here。
答案 1 :(得分:2)
非托管资源应在if(disposing)
部分之外部署。在那里只应处理管理资源。
在COM包装器中:
private void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
//Dispose managed resource if any.
}
//Release the unmanaged resource.
disposed = true;
}
}
并保持Dispose Pattern的实现,因为COM包装器实现了IDisposable。
我不确定ReleaseComObject
。显然是not allways recommended。还有Marshal.FinalReleaseComObject方法。另请参阅有关如何包装COM对象的answer。
有关如何实施配置模式的详细指南,您可以阅读Joe Duffy撰写的blog entry。它很长但很有用。