简体   繁体   English

C#/ CLI:如果在其中使用Dispose(),则不会调用析构函数

[英]C#/CLI: Destructor not called if Dispose() used in it

I have a C++/CLI class named "CTransferManaged" with implemented finalizer and destructor: 我有一个名为“CTransferManaged”的C ++ / CLI类,带有实现的终结器和析构函数:

CTransferManaged::~CTransferManaged()
{
    this->!CTransferManaged();
}
CTransferManaged::!CTransferManaged()
{
    //Clean up resources... 
}

This class is wrapped with a C# class named "CTransfer" containig an object m_transfer of type CTransferManaged. 这个类包含一个名为“CTransfer”的C#类包含一个CTransferManaged类型的对象m_transfer。

If the destructor of this class only clears the reference to the object m_transfer I can see that the destructor is called (breakpoint is hit): 如果此类的析构函数只清除对象m_transfer的引用,我可以看到析构函数被调用(命中断点):

~CTransfer()
{
    m_transfer = null; //breakpoint on this line
}

If I call the Dispose() function of the m_transfer object without changing anything else, the destructor is not called anymore (breakpoint no more hit). 如果我调用m_transfer对象的Dispose()函数而不更改其他任何东西,则不再调用析构函数(断点不再命中)。 Any guesses why? 任何猜测为什么?

~CTransfer()
{
    m_transfer.Dispose(); //breakpoint on this line
    m_transfer = null;
}

I would like to call Dispose() manually since I found out that the resources of the C++/CLI object (m_transfer) are not cleaned up properly if I don't call Dispose manually. 我想手动调用Dispose(),因为我发现如果我不手动调用Dispose,则不会正确清理C ++ / CLI对象(m_transfer)的资源。 At the moment I don't know exactly why. 目前我不确切知道为什么。

Why is the destructor of CTransfer (C# class) no more called as soon as it calls CTransferManaged::Dispose() (C++/CLI)? 为什么一旦调用CTransferManaged :: Dispose()(C ++ / CLI)就不再调用CTransfer(C#类)的析构函数?

C# destructor only get called by the garbage collector and you can not call it directly. C#析构函数只能被垃圾收集器调用,你不能直接调用它。

Dispose which is part of IDisposalbe interface should be only called manually and it will not fire the destructor. 作为IDisposalbe接口的一部分的Dispose只应手动调用,它不会触发析构函数。

Instead of relying on destructor try to implement iDisposabe and called the Dispose method directly and put your code there. 而不是依赖析构函数尝试实现iDisposabe并直接调用Dispose方法并将代码放在那里。

If the Resource class contains embedded objects that should be disposed, this pattern is needed with C#: 如果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);
   }
}

The typical pattern for Disposing and Finalizing is such that when you call Dispose, the finalizer should be suppressed. Disposing和Finalizing的典型模式是,当您调用Dispose时,应该抑制终结器。 Dispose is intended to clear resources as soon as it is executed, whereas the finalizer is meant to clear resources whenever the garbage collector collects the class... Both are intended to do the same thing (release unmanaged resources), and so if you call Dispose, calling the finalizer would then be redundant and unnecessary, and would also cause the object to live longer than it needs to since it would first be placed on the Finalizer queue before being collected and destructed. Dispose用于在执行后立即清除资源,而终结器用于在垃圾收集器收集类时清除资源...两者都旨在执行相同的操作(释放非托管资源),因此如果您调用处理,调用终结器将是多余的和不必要的,并且还将导致对象比它需要的寿命更长,因为它在被收集和销毁之前首先被放置在Finalizer队列上。 This causes poor memory management on highly accessed applications which create and dispose many objects. 这会导致在高度访问的应用程序上进行糟糕的内存管理,这些应用程 Therefore, most Dispose methods in C# will call: 因此,C#中的大多数Dispose方法都会调用:

GC.SuppressFinalize(this);

Which tells the Garbage collector to not do the finalizer. 这告诉垃圾收集器不做终结器。 This pattern is widely used and is likely utilized in your unmanaged class as well. 这种模式被广泛使用,也可能在你的非托管类中使用。 This is probably why the Dispose call eliminates the destructor. 这可能是Dispose调用消除析构函数的原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM