SafeHandle…


I haven't been paying much attention to Whidbey stuff in the past year or so, but today I came across something that I hadn't known about (or, perhaps, hadn't really understood).


If you've written code in C#, it's likely that you've done some interop, and faced "the cleanup problem", where you have to write finalizers, implement IDisposable, etc. That's really not that bad once you get your head around it (assuming you can ignore some of the corner cases), but the underlying system has some issues with it, covered by Chris in this post. I was going to say "summarized", but that's not an appropriate description for what Chris does...


Anyway, the short story is that for Whidbey, there's been a new abstraction added in the form of a SafeHandle, which is something like a C++ smart pointer, but with GC-based rather than scope-based semantics. It provides a stronger contract around being run in all situations, and makes things nicer for the GC because the finalizer is only in the SafeHandle-derived class, not in the object that holds it.


To expand a bit:


In the current way of doing things, if I have a class that has an IntPtr to hold an unmanaged resource and some other member variables, those other member variables can't be collected until I'm finalized (strictly speaking, until the next GC after I'm finalized). This is unfortunate, since, having survived the first GC due to needing finalization, these objects will be promoted to the next generation.


With a SafeHandle instead, the SafeHandle needs to be finalized, but the rest of the object - and any objects they reference - can be reclaimed at the first GC. That's nice.


Note that this does not remove the need for IDisposable - if I want to be sure that something is reclaimed, I need to do it myself, rather than waiting for a GC at some time in the future.


So, what does that mean?


Well, it means that if you're writing code for Whidbey, you should avoid IntPtr for handles, and use SafeHandle instead. There are several prebuilt classes that may work for you in the Microsoft.Win32.SafeHandles namespace).

Skip to main content