Banyak orang berpikir bahwa metode Dispose() dipanggil secara internal dalam metode Close(), jadi tidak ada perbedaan yang mendasar! Faktanya, pandangan ini tidak terlalu akurat.
Untuk beberapa kelas, memang benar bahwa tidak ada perbedaan mendasar antara Close() dan Dispose(), namun untuk beberapa kelas tidak demikian!
Pertama, mari kita lihat perbedaan antara metode Close() dan metode Dispose() pada SqlConnection yang paling sering kita gunakan:
Metode Dispose() kelas SqlConnection diwarisi dari kelas Komponen. Kode sumbernya adalah sebagai berikut:
kekosongan publik Buang() {
Buang(benar); //Panggil kelebihan Buang dengan parameter
GC.SuppressFinalize(this); //Meminta sistem untuk tidak memanggil finalizer dari objek yang ditentukan.
}
virtual void terlindung Buang(bool membuang) {
jika (membuang) {
kunci(ini) {
if (situs != null && situs.Container != null) {
situs.Container.Remove(ini);
}
if (peristiwa != null) {
Pengendali EventHandler = (EventHandler)acara[EventDispose];
if (handler != null) handler(ini, EventArgs.Empty);
}
}
}
}
Deskripsi metode Close() kelas SqlConnection di MSDN adalah sebagai berikut:
Tutup koneksi ke database. Ini adalah metode yang disukai untuk menutup koneksi terbuka. Jika SqlConnection berada di luar cakupan, maka SqlConnection tidak akan ditutup. Karena
Oleh karena itu, sambungan harus ditutup secara eksplisit dengan memanggil Tutup atau Buang. Tutup dan Buang secara fungsional setara. Jika nilai kumpulan koneksi
Pooling Jika diatur ke true atau yes, koneksi yang mendasarinya akan dikembalikan ke pool koneksi. Di sisi lain, jika Pooling diatur ke false atau tidak, maka
Koneksi yang mendasari ke server ditutup.
Dari uraiannya terlihat bahwa metode Close() dan metode Dispose() serupa. Faktanya, keduanya hanya setara dalam fungsi menutup koneksi.
() kode sumber metode:
timpa kekosongan publik Tutup() {
IntPtr hscp;
Bid.ScopeEnter(keluar hscp, "<sc.SqlConnection.Close|API> %d#" , ObjectID);
mencoba {
Statistik SqlStatistics = null;
RuntimeHelpers.PrepareConstrainedRegions();
mencoba {
#jika DEBUG
objek initialReliabilitySlotValue = Thread.GetData(TdsParser.ReliabilitySlot);
RuntimeHelpers.PrepareConstrainedRegions();
mencoba {
Thread.SetData(TdsParser.ReliabilitySlot, benar);
#endif //DEBUG
statistik = SqlStatistics.StartTimer(Statistik);
// Kunci di sini adalah untuk melindungi dari perintah.cancel / connection.close
kondisi balapan
// SqlInternalConnectionTds disetel ke OpenBusy selama penutupan, setelah ini
yang terjadi cast dibawah ini akan gagal dan
// perintah tersebut tidak lagi dapat dibatalkan
dapat membatalkan operasi penutupan, tapi ini
// di luar cakupan Whidbey RTM. Lihat (SqlCommand::Cancel) untuk yang lainnya
kunci.
kunci (Koneksi Dalam) {
InnerConnection.CloseConnection(ini, ConnectionFactory);
}
// tidak memerlukan GC.KeepAlive(ini) karena OnStateChange
if (null != Statistik) {
ADP.TimerCurrent(keluar _statistics._closeTimestamp);
}
#jika DEBUG
}
Akhirnya {
Thread.SetData(TdsParser.ReliabilitySlot, initialReliabilitySlotValue);
}
#endif //DEBUG
}
tangkapan (Sistem.OutOfMemoryException e) {
Batalkan(e);
melemparkan;
}
menangkap (Sistem.StackOverflowException e) {
Batalkan(e);
melemparkan;
}
catch (Sistem.Threading.ThreadAbortException e) {
Batalkan (e);
melemparkan;
}
Akhirnya {
SqlStatistics.StopTimer(statistik);
}
}
Akhirnya {
SqlDebugContext sdc = _sdc;
_sdc = nol;
Tawaran.ScopeLeave(ref hscp);
jika (sdc != nol) {
sdc.Buang();
}
}
}
Anda dapat melihat bahwa metode Close() tidak memanggil metode Dispose() Meskipun ada baris sdc.Dispose();, ini hanya melepaskan SqlDebugContext.
Misalnya, tidak ada hubungannya dengan metode SqlConnection.Dispose()!
Jadi apa bedanya?
Metode Close() hanya menutup koneksi, dan kemudian koneksi disimpan di kumpulan koneksi, jadi setelah memanggil metode Close(), Anda masih bisa meneruskannya
Metode Open() untuk membuka koneksi dan setelah memanggil metode Dispose(), koneksi tidak dapat digunakan lagi!
Perbedaan penting lainnya adalah ketika metode Close() tidak memanggil GC.SuppressFinalize(this);, konsekuensi langsungnya adalah sampah.
Operasi penghentian diperlukan selama daur ulang, yang akan menyebabkan "usia generasi" benda ini meningkat, sehingga sangat menunda waktu daur ulang benda ini!
Untuk kelas SqlConnection, jika Anda perlu menggunakan koneksi ini di masa mendatang, Anda bisa menggunakan metode Close() untuk menutup koneksi sementara.
Untuk menggunakan koneksi ini, Anda dapat menggunakan metode Dispose() terlebih dahulu untuk melepaskan sumber daya. Tentu saja, Anda dapat menggunakan kata kunci menggunakan untuk menyederhanakan proses ini.
Saya belum menemukan kode sumber kelas OleDbConnection dan kelas OdbcConnection, tetapi seharusnya mirip dengan kelas SqlConnection!
Mari kita lihat kelas yang umum digunakan dan lihat perbedaan antara metode Close() dan metode Dispose() pada kelas FileStream:
Metode Close() dari kelas FileStream diwarisi dari kelas Stream. Kode sumbernya adalah sebagai berikut:
kekosongan virtual publik Tutup()
{
Buang(benar);
GC.SuppressFinalize(ini);
}
Metode Dispose() kelas FileStream diwarisi dari kelas Stream. Kode sumbernya adalah sebagai berikut:
kekosongan publik Buang()
{
Menutup();
}
Ini merupakan implementasi dari mode Dispose standar. Metode Close() memanggil metode Dispose dengan parameter, lalu memanggil GC.SuppressFinalize.
(ini); Meminta sistem untuk tidak memanggil finalizer dari objek yang ditentukan. Metode Dispose() secara langsung memanggil metode Close()!
Untuk kelas FileStream, tidak ada perbedaan antara metode Close() dan metode Dispose()!