簡體   English   中英

什么是Winforms停車窗

[英]What are Parking Windows in Winforms

這是對此答案的后續問題https://stackoverflow.com/a/20584601/2530848

我的印象是Control類沒有實現finailzer,這確實是真的,因此泄漏的控件永遠泄露,在最終確定期間沒有清理。

Hans Passant在評論部分提供了一些提示,說明了它,以及一些關鍵字ParkingWindow 我用Google搜索了該關鍵字,找不到任何有用的資源。

最后我通過反編譯器在System.Windows.Forms.Application.ParkingWindow找到了一個名為ParkingWindow的類,我無法理解正在做什么。

看起來像無人看管的窗戶將成為這個停車窗口的父級,后來在某些時候被摧毀但不確定。

問題究竟是ParkingWindow及其用途是什么?

編輯:這與Control的Finalization或cleanup有什么關系?

后來在某些時候被摧毀但不確定

“不確定”是問題的症結所在。 這種情況經常出錯,窗戶根本沒有被破壞。

Shawn Farka的博客文章很好地解釋了停車窗的原始意圖。 必須重新創建子窗口的費用當然是最重要的。 並不是唯一的手段,雖然,某些類型的子窗口很難准確地重新創建。 TreeView是一個很好的例子,相當多的運行時狀態與它相關聯。 要准確地執行此操作,您必須記錄每個節點的折疊狀態。 這很痛苦,Winforms實際上並沒有這樣做。 當你重新分配,比如CheckBoxes或StateImageList屬性時,你會發現這是錯誤的。

總而言之,這是一個很好的伎倆,但他們過分了。 當父窗口被重新創建時,子控件不僅(暫時)在停車窗口上結束,它還會在以下情況下移動到那里:

  • 您將其Parent屬性設置為null
  • 您使用父級的Controls集合的Remove / At()方法
  • 您使用父級的Controls集合的Clear()方法

特別是最后兩個子彈在典型的Winforms程序中幾乎總是致命的 當程序員在運行時動態添加和刪除控件時,往往會使用它們。 問題是,控件重新托管在停車窗口上,但程序員只是忘記了它們,失去了對控件的引用。 他們將永遠生活在那里。 直到用戶終止程序,因為它變成了慢速糖蜜,因為它創建了數千個窗口。 或者程序因“創建窗口句柄錯誤”而崩潰。 當程序創建10,000個窗口后Windows出現陰沉時會發生這種情況。

相反, 需要調用控件的Dispose()方法。 在.NET中非常不尋常,調用Dispose()始終是可選的。 不是在Control類的情況下,停車窗口保持對控件的引用,從而阻止終結器運行。

這篇文章由MS的Shawn Burke撰寫: Windows Forms Parking Window

我們使用Windows Forms的目標之一就是嘗試盡可能地消除Win32的奇怪之處。 其中一個主要的問題是窗口句柄(HWND)管理和生命周期。 我們當然不希望普通用戶需要擔心這些問題。 在大多數情況下,這很容易。 您只需收集所有狀態,然后當您確實需要顯示窗口時,按需創建,然后從HWND而不是內部成員驅動您的狀態。

嗯,這並不總是那么好用。 請參閱,創建窗口后,您無法更改Win32窗口的某些屬性。 例如,邊框的樣式。 因此,要在創建窗口后允許用戶更改邊框樣式,您需要重新創建句柄。 這意味着您不僅需要從現有狀態中拉出所需的所有狀態,而且需要重新創建它並將其推回。好的,這不是太難。

但那些孩子呢? 哦,小提琴。 孩子們。

如果您正在修改邊框的窗口有子項,則銷毀其句柄也會破壞其所有子項的句柄。 然后你需要重新創建它們,這是非常昂貴的。 昂貴是壞事。

進入停車窗口。 停車窗口是我們解決這個問題的方法。 在某個地方你可以“停放”HWND,直到你有適合他們的父母。 把它想象為Window Handle Foster Care,但是看不見。

所以在手柄重新創建的情況下,我們會檢查是否有孩子。 如果有的話,我們(如果需要的話)創建停車窗口,讓子項為父項,重新創建父項的句柄,然后將它們移回。 工作得很好,雖然管理停車窗口的生命周期確實導致了一些問題......

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM