2009-12-28 20 views
8

Temizle() .NET bileşeni kaplarda ing öğeler değil imha onları (Dispose (gerçek) çağırarak yaptığı gerçeği hakkında birden ipler (a, b, c vs.) vardır.Temizle kontroller bunları bertaraf etmez - risk nedir?

en sık IMHO, Clear-ed bileşenleri uygulamada artık kullanılmamaktadır, bu yüzden açıkça ana kutularından silme sonra Elden gerekiyor.

Belki koleksiyonun Clear yöntem bir bool vardı iyi bir fikirdir parametre dispose, true olduğunda, toplama öğeleri listeden kaldırılmadan önce de imha edilir?

+0

, onlar tanzim alacak. Olmazsa, muhtemelen (programcı kabul edilen uygulamaları izlediyse) imha edilmek üzere yönetilmeyen bir şey yoktur ve sadece onları toplamak için çöplük vardır. –

+0

@Aviad: Dispose yönteminin GC tarafından hiçbir zaman çağrılmayacağı sorusu, bu nedenle koleksiyonda Temizle'yi çağırmadan önce tek tek yapmanız gerekir. – serhio

+0

Demek istediğim, eğer kontrolün programcısı sonlandırıcıya bir Atma çağrısı koymadıysa (nesne çöp toplandığında çağrılır) - o zaman muhtemelen atılacak hiçbir şey yoktur. –

cevap

15

Bunun gibi değişiklikler istemek anlamsız, Windows Forms ekibi bir süre önce dağıtıldı. Bakım modunda, sadece güvenlik sorunları ve işletim sistemi uyumsuzlukları dikkate alınır.

Bunu yapmak için kendi yöntemini oluşturmak için yeterli aksi basittir:

Şimdi
public static class ExtensionMethods { 
    public static void Clear(this Control.ControlCollection controls, bool dispose) { 
     for (int ix = controls.Count - 1; ix >= 0; --ix) { 
     if (dispose) controls[ix].Dispose(); 
     else controls.RemoveAt(ix); 
     } 
    } 
    } 

yazabilirsiniz:

panel1.Controls.Clear(true); 
+1

IIRC, '' Kontrol'ü Kullanırken '' kontrol '' seçeneğini işaretlediğinizde, kontrol otomatik olarak ilgili 'ControlCollection' kontrolünden kaldırılır. Aslında 'RemoveAt '' a ihtiyacınız yoktur (ve bir“ IndexOutOfRangeException ”ile sonuçlanabilir). – Aaronaught

+0

evet ... en azından .NET 2 için bu çalışmaz. Ama soru başka bir şey. Bertaraf etmeden "Temizle" yi çağırmak bir "risk" var mı? – serhio

+2

Elbette, kontrolleri sızdırmazsınız. Diğer konulardan açık değil miydi? –

0

"risk nedir" sorusunu, risk cevaplama (ya da bir risk) bir süre alabilir, ancak pencere tutamaçlarından tükeniyor.

Komut dosyasından bir pencere oluşturan bir "pencere tasarımcısı" var. Komut dosyasını her değiştirdiğimde, pencere yeniden oluşturulur (denetimler temizlendi ve okundu). Özellikle karmaşık bir pencere ile ve her seferinde Controls.Clear()'u kullanarak, birçok düzinelerce yenilemeden sonra, sonunda "artık pencere tanıtıcıları" istisnası alacak ve daha fazla kontrol oluşturamayacağım. gibi bir şeyle Controls.Clear() çağrıyı yerine yeterince kolay

: sonlandırıcıyı imha çağrısı varsa

Controls.Cast<Control>().ForEach(c => c.Dispose());