c# /CLI:如果在其中使用Dispose(),则不调用析构函数
C#/CLI: Destructor not called if Dispose() used in it
我有一个名为"CTransferManaged"的c++/CLI类,实现了终结器和析构器:
CTransferManaged::~CTransferManaged()
{
this->!CTransferManaged();
}
CTransferManaged::!CTransferManaged()
{
//Clean up resources...
}
这个类被一个名为"CTransfer"的c#类包装,该类包含一个类型为CTransferManaged的m_transfer对象。
如果该类的析构函数只清除对对象m_transfer的引用,则可以看到析构函数被调用(击中断点):
~CTransfer()
{
m_transfer = null; //breakpoint on this line
}
如果我调用m_transfer对象的Dispose()函数而不更改任何其他内容,则不再调用析构函数(不再击中断点)。猜猜为什么?
~CTransfer()
{
m_transfer.Dispose(); //breakpoint on this line
m_transfer = null;
}
我想手动调用Dispose(),因为我发现c++/CLI对象(m_transfer)的资源没有被正确清理,如果我不手动调用Dispose。现在我不知道确切的原因。
为什么CTransfer (c#类)的析构函数不再调用CTransferManaged::Dispose() (c++/CLI)?
c#析构函数只能由垃圾回收器调用,不能直接调用
Dispose是idisposalable接口的一部分,只能手动调用,它不会触发析构函数。
不要依赖析构函数,尝试实现iDisposabe并直接调用Dispose方法,并将代码放在那里。
如果Resource类包含应该被丢弃的嵌入对象,c#需要使用这种模式:
// C#
public class Resource : IDisposable
{
private EmbeddedResource embedded;
public Resource()
{
Console.WriteLine("allocating resource");
embedded = new EmbeddedResource();
}
~Resource()
{
Dispose(false);
}
protected virtual void Dispose(bool disposing)
{
Console.WriteLine("release resource");
if (disposing)
{
embedded.Dispose();
}
}
public void Dispose()
{
Dispose(true);
}
}
处置和终结的典型模式是这样的:当调用处置时,终止器应该被抑制。Dispose的目的是在执行时立即清除资源,而终结器的目的是在垃圾收集器收集类时清除资源……两者的目的都是做同样的事情(释放非托管资源),因此,如果调用Dispose,调用终结器将是多余和不必要的,并且还会导致对象的生存时间比它需要的更长,因为它在被收集和销毁之前首先被放置在终结器队列中。这会导致高访问应用程序的内存管理不佳,这些应用程序会创建和处理许多对象。因此,c#中的大多数Dispose方法将调用:
GC.SuppressFinalize(this);
告诉垃圾收集器不执行终结器。此模式被广泛使用,并且很可能也在非托管类中使用。这可能就是Dispose调用消除析构函数的原因。
- 析构函数调用
- 在具有向量的类构造函数中进行析构函数调用
- 从 c++ 中派生类的析构函数调用虚函数
- C++析构函数调用两次,堆栈分配的复合对象
- C++ 在析构函数调用之前删除的动态成员数组
- 析构函数调用c++中的一个向量
- Singleton模式中的手动析构函数调用:调用多次
- 从内部类的析构函数调用虚拟函数
- 与 boost odeint 集成期间的析构函数调用
- 堆栈展开如何与析构函数调用有关?
- C++:优化析构函数调用
- 以逗号分隔的表达式中的析构函数调用
- GCC 9.1 返回 void& 作为显式析构函数调用的结果类型。这是一个错误吗?
- 从C++中的虚拟析构函数调用虚拟方法
- 从指针返回对象时出现意外的析构函数调用
- 使用 decltype 显式析构函数调用
- C++析构函数调用了错误的对象
- 了解虚拟函数和析构函数调用
- 多重继承析构函数调用他自己和父析构函数?c++
- 析构函数调用表单不适当的库