Amalan Terbaik dalam menggunakan Buang dan Selesaikan di. Bersih

Microsoft .Net Framework menyediakan pengumpul sampah yang berjalan di latar belakang dan melepaskan memori yang ditempati oleh objek yang diuruskan ketika mereka tidak dirujuk lagi dalam kod anda. Walaupun pengumpul sampah mahir membersihkan memori yang ditempati oleh objek yang diuruskan, tidak dijamin memori yang ditempati oleh objek yang tidak dikelola akan dibersihkan ketika kitaran GC berikutnya dijalankan. Sekiranya anda mempunyai sumber yang tidak dikendalikan dalam aplikasi anda, anda harus memastikan bahawa anda melepaskan sumber tersebut dengan jelas apabila anda selesai menggunakannya. Dalam artikel ini, saya akan menyoroti amalan terbaik yang harus anda ikuti untuk membersihkan sumber yang digunakan dalam aplikasi anda.

GC menggunakan generasi untuk mengekalkan dan mengurus jangka hayat relatif objek yang dibuat dalam memori. Objek yang dibuat baru ditempatkan pada generasi 0. Asumsi dasar adalah bahawa objek yang baru dibuat mungkin mempunyai masa hidup yang lebih pendek sementara objek yang sudah tua, mungkin mempunyai jangka hayat yang lebih lama. Apabila objek yang berada dalam generasi 0 tidak diambil semula selepas kitaran GC, objek tersebut dipindahkan ke generasi 1. Begitu juga, jika objek yang berada dalam generasi 1 bertahan dari pembersihan GC, objek tersebut dipindahkan ke generasi 2. Perhatikan bahawa GC berjalan lebih kerap di generasi yang lebih rendah daripada yang lebih tinggi. Jadi, objek yang berada di generasi 0 akan dibersihkan lebih kerap berbanding dengan objek yang berada di generasi 1. Jadi,adalah amalan pengaturcaraan yang lebih baik untuk memastikan bahawa anda menggunakan lebih banyak objek tempatan yang objek dalam ruang lingkup yang lebih tinggi untuk mengelakkan objek dipindahkan ke generasi yang lebih tinggi.

Perhatikan bahawa apabila anda mempunyai pemusnah di dalam kelas anda, waktu proses memperlakukannya sebagai kaedah Finalize (). Oleh kerana penyelesaiannya mahal, anda hanya boleh menggunakan alat pemusnah jika diperlukan - apabila anda mempunyai beberapa sumber di kelas anda yang perlu anda bersihkan. Apabila anda mempunyai finalis di kelas anda, objek dari kelas tersebut akan dipindahkan ke barisan finalisasi. Sekiranya objek dapat dijangkau, objek tersebut akan dipindahkan ke barisan "Freachable". GC mengambil semula memori yang ditempati oleh objek yang tidak dapat dicapai. Secara berkala, GC memeriksa apakah objek yang berada dalam barisan "Freachable" dapat dicapai. Sekiranya tidak dapat dicapai, memori yang ditempati oleh objek tersebut akan diambil semula. Oleh itu, jelas bahawa objek yang berada di barisan "Boleh dilalui" memerlukan lebih banyak masa untuk dibersihkan oleh pengumpul sampah.Menjadi pemusnah kosong di kelas C # anda adalah amalan yang tidak baik kerana objek untuk kelas tersebut akan dipindahkan ke barisan finalisasi dan kemudian ke barisan "Boleh dilalui" jika perlu.

Penyelesai dipanggil secara tersirat ketika memori yang ditempati oleh objek itu diambil semula. Walau bagaimanapun, pemenang tidak dijamin dipanggil oleh GC - ia mungkin atau mungkin tidak dipanggil sama sekali. Pada hakikatnya, finalis berfungsi pada mod non-deterministik - masa berjalan tidak menjamin bahawa pemenang akan dipanggil sama sekali. Anda bagaimanapun boleh memaksa pemenang final dipanggil walaupun itu sama sekali tidak menjadi amalan yang baik kerana ada hukuman yang berkaitan. Penyelesai harus selalu dilindungi dan selalu digunakan untuk membersihkan sumber yang diuruskan sahaja. Anda tidak boleh memperuntukkan memori di dalam finalizer, menulis kod untuk melaksanakan keselamatan thread atau menggunakan kaedah maya dari dalam finalis.

Kaedah Buang di sisi lain memberikan pendekatan "pembersihan deterministik" ke arah pembersihan sumber di .Net. Walau bagaimanapun, kaedah Buang tidak seperti penyelesai harus disebut dengan jelas. Sekiranya anda mempunyai kaedah Buang yang ditentukan dalam kelas, anda harus memastikan bahawa kaedah itu dipanggil. Oleh itu, kaedah buang mesti dipanggil secara eksplisit oleh kod pelanggan. Tetapi bagaimana jika anda lupa memanggil Kaedah buang yang didedahkan oleh kelas yang menggunakan sumber yang tidak dikendalikan? Pelanggan contoh kelas yang menerapkan antara muka IDisposable harus memanggil kaedah Buangkan secara terang-terangan. Dalam kes ini, anda perlu memanggil Buang dari dalam finalis. Strategi pemuktamadan deterministik automatik ini memastikan bahawa sumber yang tidak dikendalikan yang digunakan dalam kod anda dibersihkan.

Anda harus melaksanakan IDisposable pada setiap jenis yang mempunyai finalis. Merupakan amalan yang disarankan untuk melaksanakan Buang dan Selesaikan apabila anda mempunyai sumber yang tidak dikendalikan di kelas anda.

Coretan kod berikut menggambarkan bagaimana anda dapat melaksanakan corak Buang Selesaikan di C #.

batal maya dilindungi Buang (bool buang)

        {

            jika (membuang)

            {

                // tulis kod untuk membersihkan objek yang diuruskan

            }

            // tulis kod untuk membersihkan objek dan sumber yang tidak dikendalikan

        }

Kaedah membuang parameter ini dapat dipanggil secara automatik dari pemusnah seperti yang ditunjukkan dalam potongan kode di bawah.

  ~ Sumber ()

        {

            jika (! dilupuskan)

            {

                dilupuskan = benar;

                Buangkan (palsu);

            }

        }