Saya ingin memperjelas situasi ini.
Menurut pedoman Microsoft, ini adalah praktik yang baik untuk memberikan Close
metode yang sesuai. Berikut ini adalah kutipan dari pedoman desain Kerangka
Pertimbangkan memberikan metode Close()
, selain Dispose()
, jika dekat adalah terminologi standar di daerah tersebut. Saat melakukannya, penting agar Anda membuat Close
implementasinya identik dengan Dispose
...
Dalam sebagian besar kasus Close
dan Dispose
metode adalah setara. Perbedaan utama antara Close
dan Dispose
dalam hal SqlConnectionObject
adalah:
Aplikasi dapat menelepon Close
lebih dari satu kali. Tidak ada pengecualian yang dihasilkan.
Jika Anda memanggil negara objek Dispose
metode
SqlConnection
akan diatur ulang. Jika Anda mencoba memanggil metode apa pun pada SqlConnection
objek yang dibuang , Anda akan menerima pengecualian.
Yang mengatakan:
- Jika Anda menggunakan objek koneksi satu kali, gunakan
Dispose
.
- Jika objek koneksi harus digunakan kembali, gunakan
Close
metode.
con.Open() con.Close();
2con.Open(); // reuse
3.con.Dispose(); // use one time con.Open(); // error
Seperti biasa jawabannya adalah: itu tergantung. Kelas yang berbeda menerapkan
IDisposable
dengan cara yang berbeda, dan terserah pada Anda untuk melakukan penelitian yang diperlukan.Sejauh ini
SqlClient
, praktik yang disarankan adalah melakukan yang berikut:Anda seharusnya menelepon
Dispose
(atauClose
*) di koneksi! Jangan tidak menunggu pengumpul sampah untuk membersihkan koneksi Anda, ini akan mengikat koneksi di kolam renang sampai siklus GC berikutnya (setidaknya). Jika Anda meneleponDispose
, tidak perlu meneleponClose
, dan karenausing
konstruk membuatnya sangat mudah untuk ditanganiDispose
dengan benar, sebenarnya tidak ada alasan untuk meneleponClose
.Koneksi secara otomatis dikumpulkan, dan panggilan
Dispose
/Close
pada koneksi tidak secara fisik menutup koneksi (dalam keadaan normal). Jangan mencoba menerapkan pengumpulan Anda sendiri.SqlClient
melakukan pembersihan pada koneksi ketika itu diambil dari kolam (seperti mengembalikan konteks database dan opsi koneksi).* jika Anda menelepon
Close
, pastikan untuk melakukannya dengan cara pengecualian-aman (yaitu menangkap atau akhirnya memblokir).sumber
conn.Close(); // Optional
Ini bukan opsional. Itu berlebihan dan tidak perlu. Anda membuang objek dua kali dan ini akan ditandai sebagai peringatan oleh beberapa alat analisis kode.using (var x = ..) { x.Dispose(); }
, dalam hal inix
benar-benar "dibuang dua kali".Anda TIDAK perlu menelepon Buang ()!
Buang () adalah untuk memanggil pengembang, Kolektor Sampah memanggil Finalize (). Jika Anda tidak memanggil Buang () pada objek Anda, setiap sumber daya yang tidak dikelola yang digunakan tidak akan dibuang sampai pengumpul sampah datang dan menyelesaikannya (dan siapa yang tahu kapan itu akan terjadi).
Skenario ini disebut Finalisasi Non Deterministik dan merupakan perangkap umum bagi pengembang .net. Jika Anda bekerja dengan objek yang menerapkan IDisposable kemudian panggil Buang () pada mereka!
http://www.ondotnet.com/pub/a/oreilly/dotnet/news/programmingCsharp_0801.html?page=last
Meskipun mungkin ada banyak contoh (seperti pada SqlConnection) di mana Anda memanggil Disponse () pada beberapa objek dan itu hanya memanggil Tutup () pada koneksi itu atau menutup pegangan file, hampir selalu merupakan taruhan terbaik Anda untuk memanggil Buang ()! kecuali Anda berencana menggunakan kembali objek dalam waktu dekat.
sumber
Dispose
.Dispose()
jika Anda tidak menggunakanusing()
dengan kelas yang mengimplementasikanIDisposable
. Jika kelas yang dipanggil mengimplementasikan IDisposable dan Anda telah membungkus penggunaannya pada halaman di dalamnyausing()
, maka Anda dapat membuangnya denganDispose()
(pun intended, jadi tembak saya). MenggunakanClose()
, bagaimanapun, direkomendasikan dengan apa pun yang secara eksplisit memanfaatkanOpen()
, AFAIK.Close
terhubung, Postgres secara otomatis mengatur pengenal koneksinull
. Dari sana, seseorang tidak dapatDispose
pengidentifikasi koneksi sql yang sudah diatur kenull
.Sebab
SqlConnection
, dari perspektif koneksi itu sendiri, mereka setara. Menurut Reflector,Dispose()
panggilanClose()
serta melakukan beberapa operasi bebas memori tambahan - kebanyakan dengan menetapkan anggota sama dengan nol.Untuk Stream, mereka sebenarnya setara.
Stream.Dispose()
cukup panggil Close ().sumber
Component
yang sepertinya tidak melakukan apa-apa untuk mencoba dan meneleponClose()
. Saya tidak bisa melihat di mana pun diDBConnection
atauSqlConnection
yang terkait dengan salah satu pemberitahuan itu. Namun memiliki pribadiDisposeMe()
yang tidak dirujuk di mana pun .Calon saran cepat ini menjadi jawaban panjang. Maaf.
Seperti yang ditunjukkan tyler dalam jawabannya yang bagus, sambil menelepon
Dispose()
adalah praktik pemrograman yang bagus. Ini karena metode ini seharusnya "menyatukan" semua sumber daya bebas yang dibutuhkan sehingga tidak ada sumber daya terbuka yang tidak dibutuhkan. Jika Anda menulis beberapa teks ke file, misalnya, dan gagal menutup file (membebaskan sumber daya), itu akan tetap terbuka dan tidak ada orang lain yang dapat menulis sampai file tersebut tiba dan melakukan apa yang seharusnya Anda miliki. selesaiSekarang, dalam beberapa kasus akan ada metode "penyelesaian" yang lebih spesifik untuk kelas yang Anda hadapi, seperti
StreamWriter.Close()
, yang menimpaTextWriter.Close()
. Memang mereka biasanya lebih cocok dengan situasi: seorang StreamWriterClose()
, misalnya, menyiram aliran dan encoder yang mendasari sebelumDispose()
objek! Keren!Namun, menelusuri MSDN Anda akan menemukan bahwa bahkan Microsoft kadang-kadang bingung oleh banyak penutup dan pembuangan. Di halaman web ini , misalnya, dalam beberapa contoh
Close()
dipanggil sebelum implisitDispose()
(lihat menggunakan pernyataan jika Anda tidak mengerti mengapa itu implisit), dan khususnya mereka tidak mau repot-repot. Kenapa bisa begitu? Saya juga bingung.Alasan saya menemukan (dan, saya tekankan, ini adalah penelitian asli dan saya pasti akan kehilangan reputasi jika saya salah) adalah yang
Close()
mungkin gagal, menghasilkan pengecualian sementara membiarkan sumber daya terbuka, sementaraDispose()
pasti akan membebaskan mereka . Itulah sebabnya aDispose()
harus selalu menjagaClose()
panggilan (maaf untuk permainan kata-kata).Dan ya, saya kira Microsoft salah menggunakan contoh itu. Mungkin cap waktu itu tidak akan pernah masuk ke file.
Saya memperbaiki kode lama saya besok.
Edit: maaf Brannon, saya tidak bisa mengomentari jawaban Anda, tetapi apakah Anda yakin itu ide yang baik untuk panggilan
Close()
padafinally
blok? Saya kira pengecualian dari yang mungkin merusak sisa blok, yang kemungkinan akan berisi kode pembersihan yang penting.Balas ke Brannon: bagus, tapi jangan lupa untuk menelepon
Close()
ketika itu benar-benar diperlukan (misalnya ketika berhadapan dengan stream - tidak tahu banyak tentang koneksi SQL di .NET).sumber
Typecast ke iDisposable, dan panggilan buang itu. Itu akan memanggil metode apa pun yang dikonfigurasi sebagai penerapan "iDisposable.Dispose", terlepas dari apa nama fungsinya.
sumber
IDisposable.Dispose
, tetapi itu tidak berarti itu namanya. Perhatikan bahwa di vb.net, ada kemungkinan fungsi terikat ke beberapa anggota antarmuka dengan nama yang tidak perlu terkait dengan fungsi tersebut.using (myObj as IDisposable)
Secara umum, kami menghadapi masalah dalam Tutup (), Batalkan () dan Buang () tetapi izinkan saya memberi tahu Anda perbedaan di antara mereka.
1) ABORT: - Saya tidak akan menyarankan untuk menggunakan ini karena ketika dibatalkan disebut klien akan menghapus koneksi tanpa memberitahu server sehingga server akan menunggu beberapa waktu (sekitar 1 menit). Jika Anda memiliki permintaan massal maka Anda tidak dapat menggunakan batalkan () karena dapat menyebabkan waktu habis untuk kumpulan koneksi terbatas Anda.
2) Tutup: - Tutup adalah cara yang sangat baik untuk menutup koneksi karena ketika menutup koneksi itu akan memanggil server dan mengakui server untuk menutup sisi itu juga.
Di sini, satu hal lagi untuk dilihat. Dalam beberapa kasus, jika kesalahan menghasilkan maka itu bukan cara yang baik untuk menulis kode akhirnya koneksi.close () karena pada saat itu keadaan komunikasi akan rusak.
3) Buang: - Ini adalah salah satu jenis penutupan tetapi setelah menutup koneksi Anda tidak dapat membukanya lagi.
Jadi coba cara ini,
sumber
client != null
tidak benar / menyesatkan karena tidak melindungi semua penggunaan. Juga, saya tidak yakin bagaimana kode dapat mencapai "koneksi ini tidak dibuka dan harus ditutup".