[英]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屬性時,你會發現這是錯誤的。
總而言之,這是一個很好的伎倆,但他們過分了。 當父窗口被重新創建時,子控件不僅(暫時)在停車窗口上結束,它還會在以下情況下移動到那里:
特別是最后兩個子彈在典型的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.