什么是Winforms停车窗

Sri*_*vel 8 .net c# winforms

这是对此答案的后续问题/sf/answers/1440922101/.

我的印象是,Control课程没有实现finailzer,这确实是真的,所以泄露的控件永远泄露,在最终确定期间没有清理.

Hans Passant在评论部分提供了一些提示,说明了它,以及一些关键字ParkingWindow.我用Google搜索了该关键字,找不到任何有用的资源.

最后,我发现了一个名为类ParkingWindowSystem.Windows.Forms.Application.ParkingWindow通过反编译器,我无法理解的是什么与做.

看起来像无人看管的窗户将成为这个停车窗口的父级,并在某些时候被摧毁,但不确定.

问题究竟是ParkingWindow什么,它用于什么?

编辑:这与Control的Finalization或cleanup有什么关系?

Han*_*ant 10

后来在某些时候被摧毁但不确定

"不确定"是问题的症结所在.这种情况经常出错,窗户根本没有被破坏.

Shawn Farka的博客文章很好地解释了停车窗的原始意图.必须重新创建子窗口的费用当然是最重要的.并不是唯一的手段,虽然,某些类型的子窗口是非常难以准确地重新创建.TreeView是一个很好的例子,相当多的运行时状态与它相关联.要准确地执行此操作,您必须记录每个节点的折叠状态.这很痛苦,Winforms实际上并没有这样做.当你重新分配,比如CheckBoxes或StateImageList属性时,你会发现这是错误的.

总而言之,这是一个很好的伎俩,但他们过分了.当父窗口被重新创建时,子控件不仅(暂时)在停车窗口上结束,它还会在以下情况下移动到那里:

  • 您将其Parent属性设置为null
  • 您使用父级的Controls集合的Remove/At()方法
  • 您使用父级的Controls集合的Clear()方法

特别是最后两个子弹在典型的Winforms程序中几乎总是致命的.当程序员在运行时动态添加和删除控件时,往往会使用它们.问题是,控件重新托管在停车窗口上,但程序员只是忘记了它们,失去了对控件的引用.他们将永远生活在那里.直到用户终止程序,因为它变成了慢速糖蜜,因为它创建了数千个窗口.或者程序因"创建窗口句柄错误"而崩溃.当程序创建10,000个窗口后Windows出现阴沉时会发生这种情况.

相反,需要调用控件的Dispose()方法.在.NET中非常不寻常,调用Dispose()始终是可选的.不是在Control类的情况下,停车窗口保持对控件的引用,从而阻止终结器运行.


Dav*_*nan 7

这篇文章由MS的Shawn Burke撰写:Windows Forms Parking Window.

我们使用Windows Forms的目标之一就是尝试尽可能地消除Win32的奇怪之处.其中一个主要的问题是窗口句柄(HWND)管理和生命周期.我们当然不希望普通用户需要担心这些问题.在大多数情况下,这很容易.您只需收集所有状态,然后当您确实需要显示窗口时,按需创建,然后从HWND而不是内部成员驱动您的状态.

嗯,这并不总是那么好用.请参阅,创建窗口后,您无法更改Win32窗口的某些属性.例如,边框的样式.因此,要在创建窗口后允许用户更改边框样式,您需要重新创建句柄.这意味着您不仅需要从现有状态中拉出所需的所有状态,而且需要重新创建它并将其推回.好的,这不是太难.

但那些孩子呢?哦,小提琴.孩子们.

如果您正在修改边框的窗口有子项,则销毁其句柄也会破坏其所有子项的句柄.然后你需要重新创建它们,这是非常昂贵的.昂贵是坏事.

进入停车窗口.停车窗口是我们解决这个问题的方法.在某个地方你可以"停放"HWND,直到你有适合他们的父母.把它想象为Window Handle Foster Care,但是看不见.

所以在手柄重新创建的情况下,我们会检查是否有孩子.如果有的话,我们(如果需要的话)创建停车窗口,让子项为父项,重新创建父项的句柄,然后将它们移回.工作得很好,虽然管理停车窗口的生命周期确实导致了一些问题......

  • 谢谢,大卫.非常有趣的文章 (2认同)