Jika saya memiliki kode berikut:
MyClass pClass = new MyClass();
pClass.MyEvent += MyFunction;
pClass = null;
Apakah pClass akan menjadi sampah yang dikumpulkan? Atau akankah ia tetap menembaki acara-acaranya setiap kali terjadi? Apakah saya perlu melakukan yang berikut untuk memungkinkan pengumpulan sampah?
MyClass pClass = new MyClass();
pClass.MyEvent += MyFunction;
pClass.MyEvent -= MyFunction;
pClass = null;
c#
.net
event-handling
garbage-collection
Tandai Ingram
sumber
sumber
Jawaban:
Untuk pertanyaan spesifik "Apakah pClass akan dikumpulkan menjadi sampah": langganan acara tidak berpengaruh pada pengumpulan pClass (sebagai penerbit).
Untuk GC secara umum (khususnya, target): tergantung apakah MyFunction statis atau berbasis instance.
Seorang delegasi (seperti berlangganan acara) ke metode instance menyertakan referensi ke instance tersebut. Jadi ya, berlangganan acara akan mencegah GC. Namun, begitu objek mempublikasikan acara (pClass di atas) memenuhi syarat untuk koleksi, ini tidak lagi menjadi masalah.
Perhatikan bahwa ini satu arah; yaitu jika kita memiliki:
maka "penerbit" akan membuat "target" tetap hidup, tetapi "target" tidak akan membuat "publisher" tetap hidup.
Jadi tidak: jika pClass akan dikumpulkan, tidak perlu berhenti berlangganan pendengar. Namun, jika pClass berumur panjang (lebih lama dari instance dengan MyFunction), maka pClass dapat membuat instance itu tetap hidup, jadi akan perlu untuk berhenti berlangganan jika Anda ingin target dikumpulkan.
Peristiwa statis, bagaimanapun, karena alasan ini, sangat berbahaya ketika digunakan dengan handler berbasis instance.
sumber
WeakReference
, dan dalam beberapa kasus itu mungkin ide yang bagus, tetapi sesering mungkin itu bukan yang kuat.Ya, pClass akan menjadi sampah yang dikumpulkan. Langganan acara tidak menyiratkan bahwa ada referensi ke pClass.
Jika tidak, Anda tidak perlu melepaskan pawang agar pClass dikumpulkan menjadi sampah.
sumber
Saat sepotong memori tidak lagi direferensikan itu menjadi kandidat untuk pengumpulan sampah. Ketika instance kelas Anda keluar dari ruang lingkup, itu tidak lagi dirujuk oleh program Anda. Tidak lagi digunakan dan karena itu dapat dikumpulkan dengan aman.
Jika Anda tidak yakin apakah sesuatu akan dikumpulkan tanyakan pada diri Anda pertanyaan berikut: apakah masih ada referensi untuk itu? Penangan event direferensikan oleh instance objek, bukan sebaliknya.
sumber
pClass
akan menjadi sampah yang dikumpulkan. Namun, jika potongan kode di atas berada di dalam kelas lain, turunan dari kelas itu mungkin tidak dihapus jika Anda tidak diaturpClass
kenull
.sumber