[英]What is the safest way to clear a container's Controls property and make sure the controls are properly disposed?
在WinForms應用程序中,我有多個實例,在其中我將一個控件添加到容器中以響應用戶操作( panel.Controls.Add(new CustomControl(...))
),然后稍后清除面板( panel.Controls.Clear()
)並重新使用它。
在生產中,該應用偶爾會引發與GDI錯誤或無法加載ImageList
有關的異常。 這通常發生在資源有限的計算機上,以及一天中大量使用該應用程序的用戶。 很明顯,我有一個GDI句柄泄漏,應該處理從容器中清除的控件,但是我發現的任何解釋都不清楚應在何時何處放置控件。
我應該在清理容器后立即處置兒童控件嗎? 就像是:
var controls = new List<Control>(_panel.Controls.Cast<Control>());
_panel.Controls.Clear();
foreach (var c in controls) c.Dispose();
還是應該在列表中跟蹤控件並在容器的Dispose()
方法中調用dispose? 如:
List<Control> _controlsToDispose = new List<Control>();
void ClearControls()
{
_controlsToDispose.AddRange(_panel.Controls.Cast<Control>());
_panel.Controls.Clear();
}
void Dispose()
{
...
foreach (var c in _controlsToDispose) c.Dispose();
}
選項2引入了另一個您需要清除的列表,這些列表將占用更多的內存。 我希望選項1帶有圍繞您提到的代碼的try catch。
在(以某種有效的方式)糾正了我的應用沒有處理清除的控件的所有情況后,我可以提出幾點:
ListViewItem
或TreeViewItem
的集合的Tag
屬性中。 它們不應該被清除,但是整個列表應該被迭代,並在父級的Dispose()
方法中調用((Control)item.Tag).Dispose()
。 在管理控制生命周期和處置方面,我找不到任何最佳實踐或建議。 我猜規則是,如果一個控件沒有結束,那么它的生命就嵌套在一個被處置的控件上,無論何時不再使用它,都必須手動處置它,或者在父控件的Dispose()
最晚的方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.