当将处置方法不会被调用?(When would dispose method not get cal

2019-07-17 14:48发布

我读这个文章有一天,不知道为什么有一个与Dispose方法一起终结。 我读到这里就以为什么你可能要处置添加到终结。 我的好奇心,当将终结被称为在Dispose方法本身? 是否有一个代码示例,或者它的基础上出事的软件运行在系统上? 如果是的话,会发生什么不具有由GC运行Dispose方法。

Answer 1:

这里的finaliser的目的就是为了防止内存泄漏安全预防措施(如果你碰巧Dispose明确)。 这也意味着你不必处理你的对象,如果你希望他们释放资源,当程序停机,因为GC将被迫完成反正收集的所有对象。

作为一个相关的问题,它从finaliser这样做时,处置对象略有不同是很重要的。

~MyClass()
{
    Dispose(false);
}

public void Dispose()
{
    Dispose(true);
    GC.SuppressFinalize(this);
}

protected void Dispose(disposing)
{
    if (!this.disposed)
    {
        if (disposing)
        {
            // Dispose managed resources here.
        }
        // Dispose unmanaged resources here.
    }
    this.disposed = true;
}

不想在你的finaliser处置管理资源的原因是,你实际上这样做可以创建他们强引用,这可能阻止GC做适当的工作,并收集他们。 非托管资源(如Win32的处理和等)应始终明确关闭/处置,当然,因为CLR没有他们的知识。



Answer 2:

这主要是为了保护自己。 你不能决定你的类的最终用户会做什么。 通过向Dispose方法提供了另外一个终结,GC将“处置”的对象,适当地释放你的资源,即使用户忘记调用Dispose()或不当使用您的类。



Answer 3:

当对象被垃圾收集终结之称。 配置需要显式调用。 在下面的代码的终结将被调用,但Dispose方法是没有的。

class Foo : IDisposable
{
  public void Dispose()
  {
    Console.WriteLine("Disposed");
  }

  ~Foo()
  {
    Console.WriteLine("Finalized");
  }
}

...

public void Go()
{
  Foo foo = new Foo();
}


Answer 4:

dispose方法必须明确调用,或者通过调用Dispose()或通过具有在using语句的对象。 GC将始终调用终结,所以如果有什么需要发生的对象被设置在终结之前,至少应该检查,以确保一切都在对象被清理。

你要避免终结,如果在所有可能的清理对象,因为它相比前手处置他们(如呼叫处理)导致额外的工作,但在终结你应该总是至少检查是否有说谎周围需要的对象即将被删除。



Answer 5:

一个重要而微妙的音符尚未提及:处置的很少考虑的目的是为了防止对象被清理过早。 与终结的对象必须仔细写,免得一个终结于预期运行。 终结不能将一个对象(*)上进行的最后一个方法调用开始前运行,但它可能最后的方法调用有时运行,如果一旦该方法完成的对象将被放弃。 守则,妥善处置的对象调用Dispose之前不能放弃的对象,所以有一个终结肆虐对代码没有危险,其使用适当的处置。 在另一方面,如果最后的方法使用一个对象利用将在终结其最后一次使用的对象引用本身的后清理实体,有可能为垃圾收集器调用敲定对象和清洁上高达仍在使用中的实体。 补救的办法是,以确保它使用要由一个终结得到清理实体必须遵循的一个方法调用,它利用了“这个”一定点的任何呼叫的方法。 GC.KeepAlive(这)是使用应该是一个很好的方法。

(*),其被扩展到主代码不跟任何对象可以是与该规则豁免的,但处置通常,或者调用,虚拟方法的非虚拟方法。



文章来源: When would dispose method not get called?