Search code examples
c#dictionaryidisposable

How to handle disposable resources within dictionary


We have some data source classes which handle operations on disposable resources, like this:

public class SomeDataStore
{
    private readonly object dictionaryLock = new object();

    private readonly Dictionary<uint, SomeDisposableClass> dataStore = new Dictionary<uint, SomeDisposableClass>();

    public bool Remove(uint key)
    {
        bool returnValue = false;

        lock (dictionaryLock)
        {
            returnValue = dataStore.Remove(key);
        }

        //OR...

        lock (dictionaryLock)
        {
            SomeDisposableClass element;

            if (dataStore.TryGetValue(key, out element))
            {
                element.Dispose();
                returnValue = dataStore.Remove(key);
            }
        }

        return returnValue;
    }

    public void Clear()
    {
        lock (dictionaryLock)
        {
            dataStore.Clear();
        }

        //OR...

        lock (dictionaryLock)
        {
            foreach (var value in dataStore.Values)
                value.Dispose();

            dataStore.Clear();
        }
    }

    //Some other Datastore access members
}

public class SomeDisposableClass : IDisposable
{
    public void Dispose()
    {
        //Dispose resources..
    }
}

Not sure which version should be better and why? Does Dictionary's Clear or Remove internally handle disposable resource?


Solution

  • Why should an element within a dictionary be disposed automatically when removed from it? It might exist in another list or whatever anyway. Having said this it´s quite dangerous to dispose an object when removing it in some collection. None of the methods you mentioned (Remove, Clear, whatever) has any knowledge on disposable objects. All those methods do is to remove the reference to your instance from the internal cache. Removing a reference to an object however doesn´t mean it should be released (GC) or even disposed (IDisposable). This in fact has nothing to do with disposable objects. Even the GC won´t release your object if there´s another reference to it existing in another list for example.

    So you should allways dispose your ressources where you have control over them - which is usually in the same context where you created them.