窗口句柄C#/。NET

时间:2008-11-17 02:49:21

标签: c# .net interop

使用窗口句柄时,是否足以使用普通的 IntPtr ,还是应该继承 SafeHandle

是否有任何重要的利弊?

感谢。

2 个答案:

答案 0 :(得分:2)

这取决于:)

如果以最终必须调用:: CloseHandle版本的方式返回句柄,那么您应始终将SafeHandle子类化。 SafeHandle为.Net Framework提供了最强大的保证,可以释放句柄。不释放IntPtr将导致资源泄漏。足够的资源泄漏最终将导致程序崩溃。

如果不需要释放句柄,那么遍历IntPtr就足够了。

答案 1 :(得分:1)

我不认为SafeHandle会增加任何价值。 MSDN对SafeHandle s(强调我的)的使用提供了以下评论:

  

SafeHandle类为处理回收安全攻击提供保护;它还提供了句柄资源的关键完成。此类允许您将包含在派生类实例中的非托管资源(例如操​​作系统句柄)的句柄传递给非托管代码。 通过回收句柄提供防范安全攻击的保护。句柄回收的一个示例是句柄的不可信用户尝试在一个线程上对资源进行排队操作,同时关闭另一个线程上的句柄。不受信任的用户会这样做,希望句柄由进程中的某个不相关的线程立即重用,并且进程内操作返回或改变调用者通常无法访问的数据。 SafeHandle还提供关键的终结:即使主机卸载AppDomain,或者正常的终结器阻塞或需要很长时间才能清理,也会运行ReleaseHandle方法。

这两个目标似乎都不适用于从Windows窗体Control对象返回的窗口句柄。对于Control Handle属性的典型用法,处理回收似乎没有实际意义,框架和操作系统会使用窗口句柄来解决任何最终问题。

另一种思考方式是:要使用SafeHandle,您必须为IsInvalid属性和ReleaseHandle方法提供实现。据我所知,Control.Handle属性将永远不会返回无效值,并且窗口句柄将仅在控件被释放时“释放”。

也就是说,框架本身在使用它时将窗口句柄包装在HandleRef对象中,这只是在非托管代码使用句柄时保护控件免受垃圾收集器的影响。在您需要窗口句柄的典型场景中,这是您不太可能需要的,但如果您可能需要它,则几乎不需要使用它。