2024-09-20 10:00:04

Finalize vs Dispose

为什么有些人使用Finalize方法而不是Dispose方法?

在什么情况下你会使用Finalize方法而不是Dispose方法,反之亦然?


当前回答

终结器用于隐式清理——当一个类管理着绝对必须清理的资源时,你应该使用它,否则你会泄漏句柄/内存等等……

正确实现终结器是出了名的困难,应该尽可能避免——SafeHandle类(在. net v2.0及以上版本中可用)现在意味着您很少(如果有的话)需要实现终结器了。

IDisposable接口用于显式清理,并且使用得更普遍——您应该使用它来允许用户在使用完对象后显式地释放或清理资源。

注意,如果您有终结器,那么您还应该实现IDisposable接口,以允许用户显式地更快地释放这些资源,而不是在对象被垃圾收集的情况下。

请参阅DG更新:处置,终结,和资源管理,我认为是最好的和最完整的一组关于终结器和IDisposable的建议。

其他回答

Finalize在该对象不再使用时由GC调用。

Dispose只是一个普通的方法,该类的用户可以调用它来释放任何资源。

如果用户忘记调用Dispose,如果类实现了Finalize,那么GC将确保它被调用。

要回答第一部分,你应该提供人们使用的例子 完全相同的类对象的不同方法。 否则就很难(甚至很奇怪)回答。

至于第二个问题,最好先读这个 正确使用IDisposable接口 它声称

这是你的选择!但是选择“处理”。

换句话说:GC只知道终结器(如果有的话)。也称为微软的析构函数)。 好的代码会同时尝试从(终结器和Dispose)进行清理。

这是我知道的最好的例子。

 public abstract class DisposableType: IDisposable
  {
    bool disposed = false;

    ~DisposableType()
    {
      if (!disposed) 
      {
        disposed = true;
        Dispose(false);
      }
    }

    public void Dispose()
    {
      if (!disposed) 
      {
        disposed = true;
        Dispose(true);
        GC.SuppressFinalize(this);
      }
    }

    public void Close()
    {
      Dispose();
    }

    protected virtual void Dispose(bool disposing)
    {
      if (disposing) 
      {
        // managed objects
      }
      // unmanaged objects and resources
    }
  }

终结器用于隐式清理——当一个类管理着绝对必须清理的资源时,你应该使用它,否则你会泄漏句柄/内存等等……

正确实现终结器是出了名的困难,应该尽可能避免——SafeHandle类(在. net v2.0及以上版本中可用)现在意味着您很少(如果有的话)需要实现终结器了。

IDisposable接口用于显式清理,并且使用得更普遍——您应该使用它来允许用户在使用完对象后显式地释放或清理资源。

注意,如果您有终结器,那么您还应该实现IDisposable接口,以允许用户显式地更快地释放这些资源,而不是在对象被垃圾收集的情况下。

请参阅DG更新:处置,终结,和资源管理,我认为是最好的和最完整的一组关于终结器和IDisposable的建议。

Dispose和Finalize之间的主要区别是:

Dispose通常由代码调用。当您调用它时,资源立即被释放。人们忘记调用这个方法,所以使用(){}语句被发明出来。当您的程序完成{}内代码的执行时,它将自动调用Dispose方法。

您的代码不会调用Finalize。它意味着由垃圾收集器(GC)调用。这意味着在将来的任何时候,只要GC决定这样做,就可以释放资源。当GC工作时,它将通过许多Finalize方法。如果你在这里面有沉重的逻辑,它会使过程变慢。这可能会导致程序的性能问题。所以小心你放进去的东西。

我个人会在Dispose中编写大部分销毁逻辑。希望这能消除困惑。