Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/270.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 什么';HandleRef和GCHandle的区别是什么?_C#_.net_Marshalling_Com Interop - Fatal编程技术网

C# 什么';HandleRef和GCHandle的区别是什么?

C# 什么';HandleRef和GCHandle的区别是什么?,c#,.net,marshalling,com-interop,C#,.net,Marshalling,Com Interop,HandleRef和GCHandle有什么区别 谢谢您提到的一个区别是: HandleRef值类型与GCHandle一样,是一种可以识别的特殊类型 由互操作封送员执行。正常的非固定GCHandle也可以防止 垃圾收集不及时,但HandleRef提供了更好的 演出虽然使用HandleRef使对象在 平台调用的持续时间是首选的,您还可以使用 GC.KeepAlive方法用于相同目的 这两种结构的要点都是防止垃圾收集器在p/Invoke调用完成之前释放资源并使句柄无效。您链接的文档表明,这些是互操

HandleRef和GCHandle有什么区别


谢谢

您提到的一个区别是:

HandleRef值类型与GCHandle一样,是一种可以识别的特殊类型 由互操作封送员执行。正常的非固定GCHandle也可以防止 垃圾收集不及时,但HandleRef提供了更好的 演出虽然使用HandleRef使对象在 平台调用的持续时间是首选的,您还可以使用 GC.KeepAlive方法用于相同目的


这两种结构的要点都是防止垃圾收集器在p/Invoke调用完成之前释放资源并使句柄无效。您链接的文档表明,这些是互操作封送员可以识别的特殊类型

我从文档中了解到,
HandleRef
本质上是更一般的
GCHandle
结构的一个特例

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

虽然
GCHandle
结构允许使用
GCHandleType
枚举的一个成员指定其包装的句柄类型,但是
HandleRef
结构是专门为将句柄包装到非托管资源而设计的。当您直接处理非托管内存时,可能会使用
GCHandle
结构,而不是Win32 API视为黑匣子的特殊句柄

这两种方法都没有必要使用。只需调用
GC.KeepAlive
,即可防止垃圾收集器过早释放资源


即使这样也可能没有必要。多年来我一直在编写P/Invoke代码,我发现只要编写正确,就不需要这些结构。如果API对象处于执行中时,类对象会被垃圾回收,那么这是应用程序中的一个错误。实际上,我希望通过异常得到失败的通知,而不是隐藏它。

“我发现,当它被正确写入时,不需要这些结构中的任何一个。”如果您不担心阻止对象被收集,因为您知道托管代码将继续引用它,但出于某种原因,您只希望非托管代码接受/保留/返回托管引用。示例用例: