C# BlockingCollection Dispose 方法

C# BlockingCollection Dispose method

Documentation of BlockingCollection<T> class 有以下注释:

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 并且在调用后结束抑制。但是,令我惊讶的是,class 中没有显式终结器,甚至没有调用 Dispose(false)。 看起来 Dispose 函数比较简单,它只是删除对不同对象的引用以加快 GC 速度。在这种情况下,GC 会在我们忘记显式调用 Dispose() 时为我们完成这项工作。

有人能看出这个 class 的内部构造吗?方法 Dispose(bool disposing) 的目的是什么?即使在不需要的情况下,也为 .NET 核心库实现此方法是常见的做法吗?

我认为有关如何正确实施处置模式的 MSDN documentation 值得一读。但是,您的问题的答案是 BlockingCollection 未密封。这意味着它可以派生。 void Dispose(bool disposing) 的原因是允许派生 classes 正确地 de-allocate 基础 class 的资源。因此,例如,我可以实现

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),Foo 最终将在 BlockingCollection 上调用 Dispose(true),并且您得到的好处是 ~ Foo() 终结器被抑制。如果 Dispose() 方法没有被调用,终结器不会被抑制,它被调用,允许 Foo 仍然释放它的非托管资源。