Finalization of ConcurrentBag containing unmanaged objects
<p>I'm having trouble handling Dispose/Finalization correctly with a <code>ConcurrentBag</code> that contains unmanaged objects. Running the below code (usually) produces an <code>ObjectDisposedException</code> (<code>Cannot access a disposed object.Object name: 'The ThreadLocal object has been disposed.'.</code>) on the call to <code>TryTake()</code>.</p>

<p>Presumably in this case the garbage collector is destroying the <code>ConcurrentBag</code> before calling A's finalizer. I had thought this would only the case if the <code>ConcurrentBag</code> itself implemented a finalizer. Is it the case that one should never touch managed objects during the finalization path?</p>

<pre><code>class A : IDisposable
{
    private readonly ConcurrentBag&lt;object&gt; _collection = new ConcurrentBag&lt;object&gt;();

    public A(string value)
    {
        if (value == null) throw new ArgumentNullException();
    }

    ~A() 
    {
        Dispose(false);
    }

    public void Dispose() =&gt; Dispose(true);

    private void Dispose(bool disposing)
    {
        if (disposing) {}

        object value;
        while (_collection.TryTake(out value))
        {
            // Cleanup value
        }
    }
}
</code></pre>

<p>Trigger the exception:</p>

<pre><code>void Main()
{
    var a = new A(null);
}
</code></pre>

<p>The following seems to work around this specific issue but I'm unsure if this is <em>safe</em>. Is there a perfectly safe implementation for this scenario?</p>

<pre><code>while (_collection.IsEmpty == false)
{
    object value;
    _collection.TryTake(out value);
    // Cleanup value
}
</code></pre>