我一直以为答案是“否”,但找不到任何消息来源说明这一点。
在下面的类(class)中,我可以在终结器(即C)中访问ReleaseUnmanaged()实例的(托管)字段/属性吗?有什么限制(如果有)? GC或终结处理将这些成员设置为null吗?

我唯一能找到的是终结器队列上的内容可以按任何顺序终结。因此,在这种情况下,由于recommendation是允许用户多次调用Dispose()的类型,所以为什么推荐的模式会因disposing boolean而烦恼呢?如果我的终结器调用Dispose(true)而不是Dispose(false),可能会发生什么不好的事情?

public class C : IDisposable
{
    private void ReleaseUnmanaged() { }

    private void ReleaseOtherDisposables() { }

    protected virtual void Dispose(bool disposing)
    {
        ReleaseUnmanaged();
        if (disposing)
        {
            ReleaseOtherDisposables();
        }
    }

    ~ C()
    {
        Dispose(false);
    }

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

最佳答案

如果有任何方式任何代码都可以引用该对象,则GC将永远不会收集任何对象。如果对一个对象存在的唯一引用是弱引用,则GC将使它们无效,从而使任何代码都无法获得对该对象的引用,随后它将能够收集该对象。

如果某个对象具有事件的终结器,则如果GC会收集该终结器(但存在终结器),则GC会将其添加到应该尽快运行终结器的对象队列中,然后取消激活它。队列中的引用将阻止GC在终结器运行之前收集对象。终结器完成后,如果该对象不存在其他引用,并且尚未重新注册其终结器,则该终结器将不复存在。

终结器访问外部对象的最大问题是:

  • 终结器将在与使用该对象的任何线程上下文无关的线程上下文中运行,但不应执行无法保证快速完成的任何操作。这通常会产生矛盾的要求,即代码在访问其他对象时使用锁定,但是在等待锁时代码不会阻塞。
  • 如果终结器具有对另一个也具有终结器的对象的引用,则不能保证哪个将首先运行。

  • 这两个因素都严重限制了带有终结器的对象安全访问其不拥有的外部对象的能力。此外,由于实现了终结处理,因此系统可能会在不存在强引用的情况下决定运行终结器,而在终结器运行之前创建并使用外部强引用。带有终结器的对象无法确定是否会发生这种情况。

    关于c# - 我可以在终结器中安全地访问引用类型实例字段/属性吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20167139/

    10-12 05:19