WPF-是否必须处置HwndSource?

WPF-是否必须处置HwndSource?,wpf,interop,idisposable,Wpf,Interop,Idisposable,我在WPF窗口(不是主窗口)中使用HwndSource,以便钩住窗口过程(WndProc)来接收一些消息: WinSource = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle); WinSource.AddHook(new HwndSourceHook(WndProc)); HwndSource实现了IDisposable。MSDN不清楚我何时/应该处理它。的文档解释了上述技术: 可以使用此方法为非显式互操作窗口返回Hwnd

我在WPF窗口(不是主窗口)中使用
HwndSource
,以便钩住窗口过程(WndProc)来接收一些消息:

WinSource = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
WinSource.AddHook(new HwndSourceHook(WndProc));
HwndSource
实现了
IDisposable
。MSDN不清楚我何时/应该处理它。的文档解释了上述技术:

可以使用此方法为非显式互操作窗口返回HwndSource。这方面的程序是:

  • 创建WindowInteropHelper实例(提供主窗口作为构造函数参数)
  • 从该WindowInteropHelper实例获取句柄属性的值
  • 将该HWND值作为参数传递给FromHwnd
  • 然后:

    如果您希望将常规AddHook消息处理添加到窗口中,则此技术非常有用。但是,无论何时创建HwndSource,您都有责任销毁它。即使处理了应用程序HwndSource的应用程序对象,这也是正确的。

    (重点是我的)

    然而,在类文档中,我们看到:

    对象生存期

    HwndSource是一个常规公共语言运行时(CLR)对象,其生存期由垃圾收集器管理。因为HwndSource表示非托管资源,所以HwndSource实现IDisposable。[…]对于某些互操作场景,可能需要从互操作代码显式调用Dispose

    关于钩子:

    实际挂钩由弱引用持有。因此,请确保管理钩子委托的生存期


    我不能给出一个完整的答案,但是根据最近的经验,我可以说您不应该过早地处理
    HwndSource
    对象,特别是在它所指的窗口关闭之前

    我刚刚调试了一个场景,如下所示:

    using(var source = HwndSource.FromHwnd(window.HWnd()))
    {
         source.AddHook(hook);
    }
    
    这样做的结果是,在源被释放后,窗口立即变得不起作用(不再处理消息)

    简要查看
    FromHwnd()
    的参考源代码,它似乎总是会为同一窗口返回相同的对象。我认为这就是为什么你不能仅仅因为你自己的代码已经用它完成了就处理
    源代码的原因。显然,
    HwndSource.Dispose()
    不仅清理了
    HwndSource
    对象,还清理了一些非托管窗口本身

    注意到这一点,现在我也看到HWndSource说:

    同步调用Dispose会立即破坏Win32窗口

    这似乎是我观察到的