Saya memiliki kode berikut
using(MemoryStream ms = new MemoryStream())
{
//code
return 0;
}
The dispose()
metode ini disebut pada akhir using
pernyataan kawat gigi }
yang benar? Karena I return
sebelum akhir using
pernyataan, apakah MemoryStream
benda tersebut akan dibuang dengan benar? Apa yang terjadi di sini?
Jawaban:
Ya,
Dispose
akan dipanggil. Ini dipanggil segera setelah eksekusi meninggalkan ruang lingkupusing
blok, apa pun cara yang diperlukan untuk meninggalkan blok, baik itu akhir eksekusi blok,return
pernyataan, atau pengecualian.Seperti yang ditunjukkan dengan benar oleh @Noldorin, menggunakan
using
blok dalam kode dikompilasi menjaditry
/finally
, denganDispose
dipanggil difinally
blok tersebut. Misalnya kode berikut:efektif menjadi:
Jadi, karena
finally
dijamin akan dieksekusi setelahtry
blok selesai dieksekusi, terlepas dari jalur eksekusinya,Dispose
dijamin akan dipanggil, apa pun yang terjadi.Untuk informasi selengkapnya, lihat artikel MSDN ini .
Tambahan:
Sedikit peringatan untuk ditambahkan: karena
Dispose
dijamin akan dipanggil, adalah ide bagus untuk memastikan bahwaDispose
tidak pernah ada pengecualian saat Anda menerapkanIDisposable
. Sayangnya, ada beberapa kelas di pustaka inti yang melakukannya dalam keadaan tertentu ketikaDispose
dipanggil - Saya melihat Anda, Referensi Layanan WCF / Proksi Klien! - dan ketika itu terjadi, akan sangat sulit untuk melacak pengecualian asli jikaDispose
dipanggil selama pengecualian tumpukan rileks, karena pengecualian asli ditelan demi pengecualian baru yang dihasilkan olehDispose
panggilan tersebut. Ini bisa sangat membuat frustrasi. Atau apakah itu membuat frustrasi? Salah satu dari keduanya. Mungkin keduanya.sumber
Dispose
akhirnya, jadi ini secara efektif bekerja dari implementasifinally
, seperti yang Anda gambarkan.using
pernyataan berperilaku persis sepertitry ... finally
blok, jadi akan selalu dijalankan di jalur keluar kode apa pun. Namun, saya yakin mereka tunduk pada situasi yang sangat sedikit dan jarang di manafinally
blok tidak dipanggil. Salah satu contoh yang dapat saya ingat adalah jika utas latar depan keluar sementara utas latar belakang aktif: semua utas selain GC dijeda, yang berartifinally
blok tidak berjalan.Sunting jelas: mereka berperilaku sama selain logika yang memungkinkan mereka menangani objek IDisposable, d'oh.
Konten bonus: mereka dapat ditumpuk (di mana jenisnya berbeda):
Dan juga dipisahkan dengan koma (dengan tipe yang sama):
sumber
Objek MemoryStream Anda akan dibuang dengan benar, tidak perlu khawatir tentang itu.
sumber
Dengan
using
pernyataan tersebut, objek akan dibuang terlepas dari jalur penyelesaiannya.Bacaan lebih lanjut...
sumber
Lihatlah kode Anda di reflektor setelah Anda menyusunnya. Anda akan menemukan bahwa kompilator mem-refactors kode untuk memastikan bahwa pembuangan dipanggil di aliran.
sumber