C# olayları ve delegate'ler: sözleşme, abonelik ve bildirim
Bu yazı C#'ta delegate ile event arasındaki farkı, abonelik sınırlarını ve çok yayınlı (multicast) çağrılarda hata davranışını açıklıyor. Yazar, olay tabanlı bildirimin tamamlanma, asenkron işleme ve abonelik ömrü konularında neye güvenilemeyeceğini de ele alıyor. Kodla birlikte okunduğunda event tasarımını daha bilinçli yapmanıza yardımcı olur.
Kilit noktalar
- Delegate bir çağrı sözleşmesidir; event ise dış kodun yalnızca += ve -= ile abone olabildiği bir sınırdır.
- Multicast çağrıda bir handler istisna fırlatırsa, listedeki sonraki handler'lar çalıştırılmaz.
- GetInvocationList tüm handler'ları çalıştırmaz; yalnızca delegate dizisini döndürür.
- async void handler'ı çağıran taraf await edemez ve istisnasını normal şekilde yakalayamaz.
- Olay ateşlenmeden önce yapılan durum değişikliği, handler hata verse bile geri alınmaz.
- Abonelik ömrünü bir sahip belirlemeli; gereksiz kalan kayıtlar için -= çağrısını planlayın.
C#'ta delegate bir çağrı sözleşmesini tanımlar, event ise bu delegate'e dış dünyadan abone olunmasını sağlayan bir sınırdır. Yazar, bu ayrımın olay tabanlı kodu okunur kılmakla birlikte her abonenin başarılı tamamlanacağı, asenkron çalışacağı ya da süresiz kayıtlı kalacağı anlamına gelmediğini vurguluyor. Yayınlayıcının durumu önce güncellemesi, olayı sonra ateşlemesi gibi örneklerle bu sınırlar somutlaştırılıyor.
Multicast çağrılarda handler'lar listedeki sırayla çalışır ve yakalanmamış bir istisna geldiğinde sonraki handler'lar çağrılmaz. Asenkron handler'larda async void'in çağıran tarafından beklenemediği, Func<Task> benzeri imzaların da çoklu kayıtta tüm görevleri otomatik izlemediği belirtiliyor. Abonelik ömrü için ise bağımlılığı kimin sahiplendiği ve aboneliğin ne zaman kaldırılacağı önemli bir karar olarak öne çıkıyor. Tam metin, örnek kodlar ve ayrıntılı açıklamalar için orijinal yazıya bakmanız önerilir.
Gerçek dünyada kullanımı
- Bir belge yönetim servisinin revizyon kaydından sonra UI ve denetim günlüğü bileşenlerini bilgilendirmesi.
- Bir kütüphane yazarının kendi sınıfında veri değişimini dış abonelere açarken delegate'in dış koddan çağrılmasını engellemesi.
- Uzun ömürlü bir yayınlayıcıya geçici bir view veya oturumun abone olduğu ve ekrandan çıkınca aboneliği kaldırdığı UI senaryosu.
Neden önemli
Olay tabanlı kodda hangi handler'ın hangi sırada çalıştığını, hangisinin hata verebileceğini ve aboneliğin ne zaman kaldırılacağını bilmek sistemin doğru davranmasını sağlar. Tamamlanma, geri alma ve asenkron davranış için açık bir sözleşme tanımlamadan event kullanmak hatalara yol açabilir.