Search code examples
c#idisposablefinalizer

Can I safely track unmanaged resources with a managed List?


Let's say I have a disposable class which uses a List<IntPtr> to keep track of unmanaged resources:

public class MyDisposableClass : IDisposable
{
    private readonly List<IntPtr> _myUnmanagedResources = new List<IntPtr>();

    ~MyDisposableClass()
    {
        Dispose();
    } 

    public void Dispose()
    {
        // What is the state of "_myUnmanagedResources," at this stage?
        // Is it safe to iterate through this list and free my unmanaged resources?
        foreach(var ptr in _myUnmanagedResources)
        {
            Marshal.FreeHGlobal(ptr);
        }
    }
}

My question: is my List<IntPtr> object 'safe' to use, as a means of tracking my allocated, unmanaged resources? What if Dispose() is called from the finalizer? Could the List object already have been GC'd by this time? If yes: is there a way to ensure it will exist during finalization?


Solution

  • The List<> class itself is not disposable and does not have a finalizer so you don't have any problems.

    It is however not completely safe, you have no protection against a misbehaving app calling your Dispose() method more than once or using an IntPtr afterwards. That will turn out poorly of course. Very simple to solve however, simply add _myUnmanagedResources.Clear();