C # Form.Close vs Form.Dispose


88

C # konusunda yeniyim ve daha önceki gönderilere bakmaya çalıştım ama iyi bir cevap bulamadım.

Tek formlu bir C # Windows Form Başvurusunda, Form.Close()daha iyi veya Form.Dispose()?

MSDN, nesne içindeki tüm kaynakların kapatıldığını ve bir Kapat çağrıldığında formun atıldığını söylüyor. Buna rağmen, Kapatma yerine Dispose'u izleyen çevrimiçi birkaç örnekle karşılaştım.

Birinin diğerine göre avantajı var mı? Hangi senaryolarda birini diğerine tercih etmeliyiz?


Biraz farklı soru, aynı cevap, IMO: yani Kapat ve Dispose genellikle eşdeğerdir, ancak Close'u birden fazla kez çağırabilirsiniz.
ChrisW

2
@Chrisw: Dispose'u birden çok kez de çağırabilirsiniz.
Henk Holterman

@ChrisW, Dispose birden fazla kez çalışacak şekilde tasarlanmalıdır. bluebytesoftware.com/blog/…
Steven Evers

Beni o kadar yakınlaştıran şey === kapatmak yerine elden çıkarmak == form.Visible = false; Bu yakınlığın, elden çıkarmaktan daha yumuşak bir yöntem olacağını bekliyordum.
Pete Kirkham

4
@Pete Kirkham: İstersen form.Visible = false;arayabilirsin form.Hide(). Aslında, form.Hide()basitçe ayarlar this.Visible = false;.
Dirk Vollmar

Yanıtlar:


172

MSDN üzerindeki bu forum size söyler.

Form.Close()win32 penceresini kapatmak için uygun Windows mesajlarını gönderir. Bu işlem sırasında, form kalıcı olarak gösterilmediyse, formda Dispose çağrılır. Formun elden çıkarılması, formun elinde tuttuğu yönetilmeyen kaynakları serbest bırakır.

Bir form1.Show()veya yaparsanız Application.Run(new Form1()), Dispose çağrıldığında Close()çağrılacaktır.

Bununla birlikte, form1.ShowDialog() formu kalıcı olarak göstermek için yaparsanız , form elden çıkarılmaz ve form1.Dispose()kendinizi aramanız gerekir . İnanıyorum ki, formu kendi başına atmak için endişelenmen gereken tek zaman bu.


1. versiyon alıntı içeriyor mu? Telafi etmek için +1.
Henk Holterman

@Dan the first version sucked ... (Üzgünüm @Kyra)
jjnguy

13
Bu, msdn.microsoft.com/en-us/library/… adresinde MSDN'nin belirttiği ile biraz aynı değildir : "Bir formun Kapat'a atılmadığındaki tek koşul, birden çok belgeli bir arabirimin (MDI) parçası olmasıdır uygulama ve form görünmez. Bu durumda, çöp toplama için formun tüm denetimlerini işaretlemek için Dispose'u el ile çağırmanız gerekir. " Bununla birlikte, basit bir örnekle modal formların imha edilip edilmediğini kontrol etmek kolay olmalıdır.
Dirk Vollmar


15

Genel bir kural olarak, yöntemi doğrudan çağırarak veya "kullanan" bir bloğa sararak, bunu sunan herhangi bir sınıf için Dispose yöntemini her zaman açıkça çağırmayı savunurum.

Çoğu zaman, IDisposible uygulayan sınıflar bunu yapar çünkü serbest bırakılması gereken bazı yönetilmeyen kaynakları sararlar. Bu sınıfların koruma görevi gören sonlandırıcılara sahip olması gerekirken, Dispose çağırmak bu belleğin daha erken ve daha düşük ek yük ile serbest kalmasına yardımcı olacaktır.

Form nesnesi durumunda, Kyra'nın bağlantısında belirtildiği gibi, Kapat yönteminin sizin adınıza Dispose'u çağırması belgelenmiştir, bu nedenle bunu açıkça yapmanız gerekmez. Ancak bana göre bu her zaman bir uygulama ayrıntısına güvenmek gibi geldi. Ben her zaman onları uygulayan sınıflar için hem Close hem de Dispose çağırmayı, uygulama değişikliklerine / hatalarına karşı ve açıklık adına korumayı tercih ederim. Düzgün uygulanan bir Dispose yöntemi, birden çok kez çağırmak için güvenli olmalıdır.



6

CloseMuhtemelen arama yapmamak, size nedenini özellikle söyleyemememe rağmen, birinin biraz önemli olduğunu düşündüğü bir sürü Win32 mesajı göndermeyi atlar ...

Closedışarıdan birinin (forma) izleyebileceği FormClosingve FormClosedbuna göre tepki verebilmesi için olayları (iptal edilebilen) artırma avantajına sahiptir .

Sadece formu elden çıkarırsanız ortaya çıkıp çıkmadığına FormClosingve / veya FormCloseddile getirilip getirilmediğine dair net değilim , ancak bunu denemeniz için size bırakacağım.


3
Formu elden çıkarırsanız, kapanış ve kapatılan olaylar çağrılmaz.
matrix

5
Dispose yöntemini çağırmak, Modal-Form üzerinde mdi-child pencere üzerinde kullanıldığında pencerenin titremesine neden oluyor
dotNETbeginner

1

Kullanmak usingoldukça iyi bir yoldur:

using (MyForm foo = new MyForm())
{
    if (foo.ShowDialog() == DialogResult.OK)
    {
        // your code
    }
}

0

Kapat () - yönetilen kaynak geçici olarak kapatılabilir ve bir kez daha açılabilir.

Dispose () - yönetilen veya yönetilmeyen kaynakları kalıcı olarak kaldırır


3
Bu, yalnızca form kullanılarak gösterildiyse geçerlidir ShowDialog(). Aksi takdirde Close()formu da elden çıkaracaktır.
Peter Duniho

-1

Formunuzda form.close () kullanırsanız ve formunuzun FormClosing Olayını ayarlarsanız ve bu Olayda form.close () kullanırsanız, sınırsız döngüye girersiniz ve Argüman aralık dışı oldu ve çözüm, formu değiştirmektir Event of FormClosing'de form.dispose () ile .close (). Umarım bu küçük ipucu size yardımcı olur !!!


-1

VS tanılama araçlarıyla henüz denediğim şey, bunu adlandırdım.Close () ve ardından tetiklenen kapanma olayı oluşturdum. Sonra Formclosing olayının sonunda this.Dispose () adını verdiğimde, içindeki diğer birçok nesneyi attığımda, her şeyi çok daha pürüzsüz bir şekilde temizliyor.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.