0

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?

BTownTKD
  • 7,911
  • 2
  • 31
  • 47
  • I'm not a COM Expert but have had forays there. Here's what I found, the COM divide is "Deep and Wide"... COM has a mind of it's own and is rarely (if ever) controlled by managed side with the exception that you understand WIN32 internals well. Bottom line is that the COM side is one big huge message pump with more messages and states than you can imagine. If you don't understand that stuff, then you can only make suggestions to that side. As far as disposal, it was at one time a crap shoot in my estimation. I personally stay away from as much COM work as possible. – JWP Dec 17 '14 at 15:18
  • What's the point on calling `GC.SuppressFinalize` on the finalizer itself? – Jcl Dec 17 '14 at 16:21

1 Answers1

2

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();

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • Thank you Hans. I've seen similar questions answered in a roudnabout way, but your answer really clarified the point: "A managed member is safe to use in a finalizer, ONLY as long as the member has no finalizer of its own." – BTownTKD Dec 17 '14 at 15:23