HandleRef和GCHandle有什么区别?

时间:2011-12-19 14:50:56

标签: c# .net marshalling com-interop

2 个答案:

答案 0 :(得分:7)

这两种结构的目的是防止垃圾收集器在P / Invoke调用完成之前释放资源并使句柄无效。您链接的文档表明这些是interop marshaller识别的特殊类型。

我从文档中收集到的是HandleRef本质上是更一般的GCHandle结构的特例。

HandleRef结构专门用于将句柄包装到与P / Invoke代码一起使用的非托管资源。例如,窗口句柄(HWND)或设备上下文(HDC)。它有一个Handle属性,返回类型IntPtr的值,这是一个整数值,它是底层系统体系结构上指针的大小。你可以快速使用它来和轻松获得它包裹的手柄。

尽管GCHandle结构允许使用GCHandleType枚举的一个成员指定它包装的句柄类型,但HandleRef结构专门用于将句柄包装为不受管理的资源。当你直接处理非托管内存时,你可能会使用GCHandle结构,而不是Win32 API作为黑盒子处理的特殊句柄。

没有必要使用它们。可以简单地调用GC.KeepAlive来防止垃圾收集器过早释放资源。

即便如此也许没有必要。我多年来一直在编写P / Invoke代码,我发现当它正确编写时,不需要这些结构中的任何一个。如果在API调用执行过程中类对象被垃圾收集,那么这就是应用程序中的错误。我实际上想要通过异常通知失败,而不是隐藏它。

答案 1 :(得分:0)

您提到的link给出了一个不同之处:

  

HandleRef值类型与GCHandle类似,是一种可识别的特殊类型   由interop marshaler。正常的非固定GCHandle也可以防止   不合时宜的垃圾收集,但HandleRef提供更好的   性能。虽然使用HandleRef来保持对象的活着   平台调用调用的持续时间是首选,您也可以使用   GC.KeepAlive方法用于相同的目的。