Reputation: 95
What's the difference between HandleRef and GCHandle?
http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.handleref.aspx
http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.gchandle.aspx
Thanks
Upvotes: 8
Views: 1296
Reputation: 244843
The point of both these structures is to prevent the garbage collector from releasing a resource and invalidating the handle before the P/Invoke call has finished. The documentation you linked indicates that these are special types recognized by the interop marshaller.
What I gather from the documentation is that HandleRef
is essentially a special case of the more general GCHandle
structure.
The HandleRef
structure is specifically intended for wrapping handles to unmanaged resources that are used with P/Invoke code. For example, window handles (HWND
) or device contexts (HDC
). It has a Handle
property that returns a value of type IntPtr
, which is an integer value the size of a pointer on the underlying system's architecture. You can use this to quickly & easily obtain the handle it wraps.
Whereas the GCHandle
structure allows one to specify the type of handle it wraps using one of the members of the GCHandleType
enumeration, the HandleRef
structure was specifically designed to wrap handles to unmanaged resources. You'd probably use the GCHandle
structure when you're dealing directly with unmanaged memory, rather than the special handles that the Win32 API treats as black boxes.
It is not necessary to use either. One can simply call GC.KeepAlive
to keep the garbage collector from prematurely releasing the resource.
And even that is probably not necessary. I've been writing P/Invoke code for years, and I've found that when it's correctly written, there's no need for either of these structures. If a class object gets garbage collected while the API call is in the middle of executing, then that's a bug in your application. I actually want to be notified of the failure via an exception, not hide it.
Upvotes: 8
Reputation: 30097
One difference is given in the link you mentioned:
The HandleRef value type, like GCHandle, is a special type recognized by the interop marshaler. A normal, nonpinned GCHandle also prevents untimely garbage collection, yet HandleRef provides better performance. Although using HandleRef to keep an object alive for the duration of a platform invoke call is preferred, you can also use the GC.KeepAlive method for the same purpose.
Upvotes: 0