Formulir C # Tutup vs Bentuk Buang

88

Saya baru mengenal C #, dan saya mencoba untuk melihat posting sebelumnya tetapi tidak menemukan jawaban yang baik.

Dalam Aplikasi Formulir C # Windows dengan bentuk tunggal, apakah menggunakan Form.Close()lebih baik atau Form.Dispose()?

MSDN mengatakan bahwa semua sumber daya dalam objek ditutup dan formulir dibuang saat Tutup dipanggil. Terlepas dari itu, saya telah menemukan beberapa contoh online yang mengikuti Buang daripada Tutup.

Apakah yang satu memiliki keunggulan dibandingkan yang lain? Dalam skenario apa kita harus memilih salah satu dari yang lain?

topgun_ivard
sumber
Pertanyaan yang sedikit berbeda, jawaban yang sama, IMO: yaitu Tutup dan Buang biasanya setara, kecuali Anda dapat memanggil Tutup lebih dari sekali.
ChrisW
2
@ Chrisw: Anda juga dapat memanggil Buang lebih dari sekali.
Henk Holterman
@ChrisW, Buang juga harus dirancang untuk dijalankan lebih dari sekali. bluebytesoftware.com/blog/…
Steven Evers
Hal yang membuat saya sedekat itu === membuang daripada menutup == form.Visible = false; Saya berharap bahwa penutupan akan menjadi metode yang lebih lembut daripada membuang.
Pete Kirkham
4
@ Pete Kirkham: Jika Anda mau, form.Visible = false;Anda dapat menelepon form.Hide(). Sebenarnya, form.Hide()cukup set this.Visible = false;.
Dirk Vollmar

Jawaban:

172

Ini forum di MSDN memberitahu Anda.

Form.Close()mengirim pesan Windows yang tepat untuk mematikan jendela win32. Selama proses itu, jika formulir tidak ditampilkan secara sederhana, Buang akan dipanggil di formulir. Membuang formulir akan membebaskan sumber daya tidak terkelola yang disimpan formulir.

Jika Anda melakukan form1.Show()atau Application.Run(new Form1()), Buang akan dipanggil saat Close()dipanggil.

Namun, jika Anda form1.ShowDialog() menunjukkan formulir secara sederhana, formulir tidak akan dibuang, dan Anda harus menelepon form1.Dispose()diri sendiri. Saya percaya ini adalah satu-satunya saat Anda harus khawatir tentang membuang formulir sendiri.

Kyra
sumber
Apakah versi pertama menyertakan kutipan? 1 sebagai kompensasi.
Henk Holterman
@Dan versi pertama tersedot ... (Maaf @Kyra)
jjnguy
13
Ini agak tidak sama dengan status MSDN di msdn.microsoft.com/en-us/library/… : "Satu-satunya kondisi saat formulir tidak dibuang di Tutup adalah saat ini merupakan bagian dari antarmuka banyak dokumen (MDI) aplikasi, dan formulir tidak terlihat. Dalam kasus ini, Anda perlu memanggil Buang secara manual untuk menandai semua kontrol formulir untuk pengumpulan sampah. " Namun, harus mudah untuk memeriksa apakah bentuk modal dibuang atau tidak dengan sampel sederhana.
Dirk Vollmar
15

Sebagai aturan umum, saya selalu menganjurkan secara eksplisit memanggil metode Dispose untuk setiap kelas yang menawarkannya, baik dengan memanggil metode secara langsung atau membungkus dalam blok "menggunakan".

Paling sering, kelas yang mengimplementasikan IDisposible melakukannya karena mereka membungkus beberapa sumber daya tak terkelola yang perlu dibebaskan. Meskipun kelas-kelas ini harus memiliki finalisator yang bertindak sebagai pengaman, memanggil Dispose akan membantu membebaskan memori itu lebih awal dan dengan overhead yang lebih rendah.

Dalam kasus objek Formulir, seperti yang dicatat oleh tautan dari Kyra, metode Tutup didokumentasikan untuk menjalankan Buang atas nama Anda sehingga Anda tidak perlu melakukannya secara eksplisit. Namun, bagi saya, itu selalu terasa seperti mengandalkan detail implementasi. Saya lebih suka untuk selalu memanggil Close dan Dispose untuk kelas yang mengimplementasikannya, untuk menjaga dari perubahan / kesalahan implementasi dan agar jelas. Metode Buang yang diterapkan dengan benar harus aman untuk dipanggil beberapa kali.

Jesse Squire
sumber
6

Tidak menelepon Closemungkin bypass mengirim banyak pesan Win32 yang menurut orang agak penting meskipun saya tidak bisa secara khusus memberi tahu Anda mengapa ...

Closememiliki keuntungan untuk mengangkat acara (yang dapat dibatalkan) sedemikian rupa sehingga orang luar (dalam bentuk) dapat menonton FormClosingdan FormCloseduntuk bereaksi sesuai.

Saya tidak jelas apakah FormClosingdan / atau FormCloseddibesarkan jika Anda hanya membuang formulir tetapi saya akan menyerahkannya kepada Anda untuk bereksperimen.

Anjing merah
sumber
3
Jika Anda membuang formulir tersebut, maka acara penutupan dan penutupan tidak akan dipanggil.
matriks
5
memanggil metode Buang akan menyebabkan jendela berkedip-kedip saat digunakan pada Modal-Form melalui jendela
mdi
1

Menggunakan usingadalah cara yang cukup bagus:

using (MyForm foo = new MyForm())
{
    if (foo.ShowDialog() == DialogResult.OK)
    {
        // your code
    }
}
Mustafa Burak Kalkan
sumber
0

Close () - sumber daya yang dikelola dapat ditutup sementara dan dapat dibuka sekali lagi.

Dispose () - secara permanen menghapus sumber daya yang dikelola atau tidak dikelola

Yuresh Karunanayake
sumber
3
Ini benar hanya jika formulir diperlihatkan menggunakan ShowDialog(). Jika tidak, Close()formulir juga akan dibuang.
Peter Duniho
-1

Jika Anda menggunakan form.close () dalam formulir Anda dan menyetel Peristiwa Penutupan Formulir dari formulir Anda dan baik menggunakan form.close () dalam Peristiwa ini, Anda berada dalam putaran tak terbatas dan Argumen di luar rentang terjadi dan solusinya adalah mengubah bentuk .close () dengan form.dispose () di Acara FormClosing. Saya harap tip kecil ini membantu Anda !!!

Hadi Erfanian
sumber
-1

Apa yang saya baru saja bereksperimen dengan alat diagnostik VS adalah saya menyebutnya this.Close () kemudian peristiwa formclosing dipicu. Kemudian Ketika saya memanggil this.Dispose () di akhir acara Formclosing di mana saya membuang banyak objek lain di dalamnya, itu membersihkan semuanya jauh lebih halus.

smoothumut
sumber