Without pointing me to MSDN, could someone give a concise, clear explanation of the purpose of each of these and when to use them. (IntPtr, SafeHandle and HandleRef)
-
9Nothing. Just looking for a brief summary of each to ensure I'm using them correctly. If I read MSDN and other folks' descriptions I get a better feel for if what I'm doing is correct. – user62572 Feb 08 '09 at 23:41
2 Answers
IntPtr
is just a simple integer-based struct that can hold a pointer (ie., 32 bit size on 32-bit systems, 64-bit size on 64-bit systems).
SafeHandle
is a class that is intended to hold Win32 object handles - it has a finalizer that makes sure that the handle is closed when the object is GC'ed. SafeHandle
is an abstract class because different Win32 handles have different ways they need to be closed. Prior to the introduction of SafeHandle
, IntPtr
was used to hold Win32 handles, but ensuring that they were properly closed and prevented from being GC'ed was the responsibility of the programmer.
HandleRef
is a way to make sure that an unmanaged handle is not GC'ed when you're in the middle of a P/Invoke call. Without something like HandleRef
, if your managed code doesn't do anything with the handle after the P/Invoke call, if the GC were run during the P/Invoke call it would not realize that the handle was still in use and might GC it. I imagine (but I'm not sure and haven't looked) that SafeHandle
might use HandleRef
as part of its management of the encapsulated handle.

- 333,147
- 50
- 533
- 760
-
16Minor correction. Use HandleRef when you don't want a *managed* object GC'ed during PInvoke. e.g class HWnd { public IntPtr Handle; } HWnd a = new HWnd(); B.SendMessage(a.Handle, ...); <-- a could be GC'ed in PInvoke B.SendMessage(new HandleRef(a, a.Handle)) <-- now a cannot be GC'ed in PInvoke – Ifeanyi Echeruo Apr 07 '09 at 04:09
-
4Another addition: `SafeHandle` includes reference counting to prevent handle recycling attacks. – Stephen Cleary Dec 02 '10 at 14:48
-
Can anyone confirm safehandle uses handleref? Or at least has a similar mechanism? – Assimilater Jun 30 '17 at 15:33
-
4@Assimilater Yes: the mechanism is similar. Both HandleRef and SafeHandle are protected from GC until the call returns; and both protect an object's finalizer from running and deleting the IntPtr. HandleRef _points to_ the object with that finalizer; while SafeHandle _is_ the object with that finalizer. – Paul Du Bois May 31 '18 at 00:50
-
Considering the structure of all three, `IntPtr` cannot be exchanged with `SafeHandle` nor with `SafeRef`, as neither `Safe*` type is 32/64 bits only, right? – Adam L. S. Feb 01 '21 at 21:02
HWnd a = new HWnd();
B.SendMessage(a.Handle, ...);
Assuming this is the only reference to "a" in the program, this is equivalent to:
HWnd a = new HWnd();
IntPtr h = a.Handle;
// a is no longer needed and thus can be GC'ed
B.SendMessage(h, ...);
The problem is that when "a" is disposed, it will close the handle. If this happens before or during the call to SendMessage, the handle will be invalid.
HandleRef prevents "a" from being garbage collected before the program is done with h.

- 201
- 2
- 2