Pertanyaan Mengapa implementasi acara di C # tidak menggunakan pola acara yang lemah secara default?


Pertanyaan ini dapat mengarah pada jawaban spekulatif tetapi saya menganggap ada keputusan desain pemikiran yang baik di belakang implementasi event di .

Pola acara di  membuat pelanggan tetap hidup selama penerbit acara tersebut masih hidup. Jadi, jika Anda tidak berhenti berlangganan, Anda membocorkan memori (baik, tidak benar-benar bocor - tetapi memori tetap tidak diperlukan).

Jika saya ingin mencegahnya, saya dapat berhenti berlangganan dari acara atau menerapkan pola acara yang lemah sebagai diusulkan di MSDN.

Dengan pola kejadian yang menyebabkan begitu banyak masalah (untuk pemula?), Pertanyaannya adalah: mengapa keputusan dibuat bahwa penerbit menyimpan referensi yang kuat kepada pelanggan, daripada membuat mereka independen atau memungkinkan pengembang untuk secara eksplisit memiliki strong atau weak pengubah?

Sudah ada beberapa pertanyaan di sini tentang topik ini dan jawabannya terdengar masuk akal, tetapi tidak ada yang benar-benar menjawab mengapa itu seperti itu.


19
2018-03-15 18:43


asal


Jawaban:


Salah satu alasannya tentu kinerja. GC menangani (yang kuasa semua referensi "eksotis" seperti WeakReference) datang dengan biaya kinerja. Kejadian lemah lebih lambat daripada acara "kuat" karena memerlukan pegangan GC. Kejadian yang kuat diimplementasikan (secara default) oleh bidang contoh yang menyimpan delegasi. Ini hanyalah referensi yang dikelola biasa semurah referensi lainnya.

Acara seharusnya menjadi mekanisme yang sangat umum. Mereka tidak hanya dimaksudkan untuk skenario UI di mana Anda mungkin memiliki beberapa lusin penangan acara. Ini bukan ide yang bijaksana untuk memanggang banyak kompleksitas dan biaya kinerja ke dalam fitur bahasa dasar.

Ada juga a perbedaan semantik dan non-determinisme itu akan disebabkan oleh referensi yang lemah. Jika Anda terhubung () => LaunchMissiles() untuk beberapa acara Anda mungkin menemukan rudal yang akan diluncurkan hanya kadang-kadang. Di lain waktu, GC telah mengambil handler. Ini bisa diselesaikan dengan pegangan tergantung yang memperkenalkan tingkat kerumitan lain.

Perhatikan, bahwa Anda dapat menerapkan sendiri peristiwa yang lemah secara transparan kepada pelanggan. Peristiwa seperti properti dalam arti bahwa mereka hanya metadata dan konvensi berdasarkan sekitar add dan remove metode aksesor. Jadi ini (hanya) pertanyaan tentang default yang dipilih bahasa .NET. Ini bukan pertanyaan desain dari CLR.

Saya pribadi merasa jarang bahwa sifat referensi yang kuat dari peristiwa adalah masalah. Seringkali, peristiwa dihubungkan di antara benda-benda yang memiliki masa hidup yang sama atau sangat mirip. Misalnya Anda dapat menghubungkan semua peristiwa yang Anda inginkan dalam konteks permintaan HTTP di ASP.NET karena segala sesuatu akan memenuhi syarat untuk pengumpulan ketika permintaan telah berakhir. Setiap kebocoran dibatasi dalam ukuran dan berumur pendek.


20
2018-03-15 19:12