WPF-是否必须处置HwndSource? [英] WPF - Does HwndSource have to be disposed?

查看:67
本文介绍了WPF-是否必须处置HwndSource?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm using HwndSource in a WPF window, which is not the main window, in order to hook a window procedure (WndProc) to receive some messages:

WinSource = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
WinSource.AddHook(new HwndSourceHook(WndProc));

HwndSource 实现 IDisposable .MSDN尚不清楚我何时/应该处置它.HwndSource.FromHwnd 解释了上面的技术:

HwndSource implements IDisposable. MSDN is not clear about when/should I dispose it. The docs of HwndSource.FromHwnd explains the technique above:

您可以使用此方法为不是显式互操作窗口的窗口返回HwndSource.此过程是:

You can use this method to return an HwndSource for a window that is not explicitly an interoperation window. The procedure for this is:

  1. 创建一个WindowInteropHelper实例(将主Window提供为构造函数参数).
  2. 从该WindowInteropHelper实例获取Handle属性的值.
  3. 将该HWND值作为参数传递给FromHwnd.

然后:

如果您随后想要向窗口添加常规的AddHook消息处理,则此技术可能很有用.但是,每创建一个HwndSource时,您还负责销毁它.即使处置了应用程序HwndSource的Application对象,也是如此.

(重点是我的)

但是,在

However, at the HwndSource class doc, we see:

对象生存期

HwndSource是常规的公共语言运行时(CLR)对象,其生存期由垃圾收集器管理.由于HwndSource表示非托管资源,因此HwndSource实现IDisposable.[...]在某些互操作方案中,可能需要从互操作代码中显式调用Dispose.

An HwndSource is a regular common language runtime (CLR) object, and its lifetime is managed by the garbage collector. Because the HwndSource represents an unmanaged resource, HwndSource implements IDisposable. [...] Calling Dispose explicitly from the interoperating code might be necessary for certain interoperation scenarios.

关于钩子:

实际的挂钩由一个弱引用持有.因此,请确保您管理挂钩代表的生命周期.

The actual hooks are held by a weak reference. Therefore, make sure that you manage the lifetime of your hook delegate.

推荐答案

我无法提供完整的答案,但是根据最近的经验,我可以说您不应该处置 HwndSource 对象过早-确切地说,直到关闭它所指的窗口才完全关闭.

I can't give a full answer to this, but based on recent experience I can say that you should not dispose the HwndSource object too soon - specifically, not at all until the window it refers to is closed.

我只是在调试一个像这样完成的场景:

I was just debugging a scenario that was done like this:

using(var source = HwndSource.FromHwnd(window.HWnd()))
{
     source.AddHook(hook);
}

这样做的结果是,在处理源之后,该窗口将立即失效(不再处理消息).

The result of this was that the window became nonfunctional (no longer processing messages) right after the source was disposed.

简短地查看 FromHwnd()的参考源,似乎它将始终为同一窗口返回相同的对象.我认为这就是为什么不能仅仅因为您自己的代码已完成而就处置 source 的原因.显然, HwndSource.Dispose()不仅可以清理 HWndSource 对象,还可以清理一些非托管窗口本身.

Looking briefly into the reference source for FromHwnd(), it seems that it will always return you the same object for the same window. I think this is why you cannot dispose source just because your own code is done with it. Apparently HwndSource.Dispose() doesn't just clean up the HWndSource object, but some of the unmanaged window itself.

注意到这一点,现在我还看到了HWndSource 文档说:

Having noticed this, now I also see the HWndSource documentation says:

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

Synchronously calling Dispose immediately destroys the Win32 window

这似乎是我所观察到的.

which seems to be what I've observed.

这篇关于WPF-是否必须处置HwndSource?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆