C#BlockingCollection Dispose方法

时间:2019-05-23 08:45:37

标签: c# blockingcollection

BlockingCollection<T>类的

Documentation有以下注释:

Always call Dispose before you release your last reference to the 
BlockingCollection<T>. Otherwise, the resources it is using will not be freed 
until the garbage collector calls the BlockingCollection<T> object's Finalize 
method.

C#中BlockingCollection<T>中的internal implementation具有以下方法:

/// <summary>
/// Releases resources used by the <see cref="T:System.Collections.Concurrent.BlockingCollection{T}"/> instance.
/// </summary>
/// <param name="disposing">Whether being disposed explicitly (true) or due to a finalizer (false).</param>
protected virtual void Dispose(bool disposing)

Dispose仅带有参数disposing: true的一次调用,并且在调用之后不执行终结处理。但是,令我惊讶的是,该类中没有显式的终结器,甚至没有Dispose(false)的调用。 看来Dispose函数相对简单,只是删除了对不同对象的引用以提高GC的速度。在这种情况下,当我们忘记显式调用Dispose()时,GC将为我们完成这项工作。

有人可以发现此类课程的内部内容吗?方法Dispose(bool disposing)的目的是什么?即使在不需要的情况下,对.NET核心库实施此方法是否是常见的做法?

1 个答案:

答案 0 :(得分:2)

我认为有关如何正确实现处置模式的MSDN documentation值得一读。但是,您的问题的答案是BlockingCollection没有密封。这意味着可以派生它。 void Dispose(bool disposing)的原因是允许派生类适当地重新分配基类的资源。因此,例如,我可以实现

class Foo : BlockingCollection<string>
{
  private bool disposed = false;

  ~Foo()
  {
    Dispose(false);
  }

  protected override void Dispose(bool disposing)
  {
    if (disposed)
    {
      return;
    }

    if (disposing)
    {
      // free managed resources
    }

    // free unmanaged resources

    disposed = true;
    base.Dispose(disposing);
  }
}

这样做,当调用Dispose()时,BlockingCollection将在Foo上调用Dispose(true),最终将在BlockingCollection上调用Dispose(true),您会得到〜Foo( )终结器被抑制。如果未调用Dispose()方法,则终结器不会被抑制,而是会调用它,从而允许Foo仍然释放其非托管资源。