Aracılığıyla paylaş


Güncelleştirilmiş .NET Core olay düzeni

Önceki

Önceki makalede en yaygın olay desenleri ele alınmıştı. .NET Core daha rahat bir desene sahiptir. Bu sürümde, EventHandler<TEventArgs> tanımında artık TEventArgsSystem.EventArgs'den türetilmiş bir sınıf olması gerektiği kısıtlaması yoktur.

Bu, sizin için esnekliği artırır ve geriye dönük olarak uyumludur. Şimdi esneklikle başlayalım. System.EventArgs uygulaması, System.Object'de tanımlanan MemberwiseClone() adlı yöntemi kullanır; bu yöntem, nesnenin sığ bir kopyasını oluşturur. Yansıma kullanmalıdır ki bu yöntem, EventArgs'den türetilmiş herhangi bir sınıf için işlevselliğini uygulayabilsin. Bu işlevin belirli bir türetilmiş sınıfta oluşturulması daha kolaydır. Bu, System.EventArgs'ten türetmenin tasarımlarınızı sınırlayan bir kısıtlama olduğu, ancak ek bir fayda sağlamadığı anlamına gelir. Aslında, FileFoundArgs ve SearchDirectoryArgs tanımlarını EventArgs'den türetmeyecek şekilde değiştirerek ayarlayabilirsiniz. Program tam olarak aynı şekilde çalışır.

Ayrıca, bir değişiklik daha yaparsanız, SearchDirectoryArgs'ı bir yapıya dönüştürebilirsiniz.

internal struct SearchDirectoryArgs
{
    internal string CurrentSearchDirectory { get; }
    internal int TotalDirs { get; }
    internal int CompletedDirs { get; }

    internal SearchDirectoryArgs(string dir, int totalDirs, int completedDirs) : this()
    {
        CurrentSearchDirectory = dir;
        TotalDirs = totalDirs;
        CompletedDirs = completedDirs;
    }
}

Ek değişiklik, tüm alanları başlatan oluşturucuyu girmeden önce parametresiz oluşturucuyu çağırmaktır. Bu ekleme olmadan C# kuralları, atanmadan önce özelliklere erişildiğini bildirir.

FileFoundArgs öğesini bir sınıftan (referans türü) bir yapıya (değer türü) dönüştürmemelisiniz. İptal durumunu işleme protokolü, olay bağımsız değişkenlerini referans olarak geçirmenizi gerektirir. Aynı değişikliği yaptıysanız, dosya arama sınıfı hiçbir olay abonesi tarafından yapılan değişiklikleri asla gözlemlemez. Her abone için yapının yeni bir kopyası kullanılır ve bu kopya, dosya arama nesnesi tarafından görülen kopyadan farklı bir kopya olur.

Şimdi bu değişikliğin geriye dönük olarak nasıl uyumlu olabileceğini düşünelim. Kısıtlamanın kaldırılması mevcut kodu etkilemez. Mevcut olay bağımsız değişken türleri, hala System.EventArgs'dan türetilmektedir. Geriye dönük uyumluluk, System.EventArgs'dan türetmeye devam etmelerinin başlıca nedenlerinden biridir. Mevcut olay aboneleri, klasik kalıba uygun bir olaya abone olan kişilerdir.

Benzer mantığın ardından, şu andan itibaren oluşturulan herhangi bir olay bağımsız değişken türünün mevcut kod temellerinde hiçbir abonesi olmaz. System.EventArgs'dan türemeyen yeni olay türleri bu kod tabanlarını bozmaz.

Asenkron abonelerle olaylar

Öğrenmeniz gereken son bir örüntü var: Zaman uyumsuz kodu çağıran olay abonelerini nasıl doğru şekilde yazacağınızı öğrenmek. Zorluk, async ve awaitmakalesinde açıklanmıştır. Asenkron yöntemlerin geçersiz bir geri dönüş türü olabilir, ancak bu önerilmez. Etkinlik aboneliği kodunuz async bir yöntemi çağırdığında, async void yöntemini oluşturmaktan başka seçeneğiniz yoktur. Olay işleyici imzası bunu gerektirir.

Bu karşıt rehberliği uzlaştırmanız gerekiyor. Bir şekilde, güvenli bir async void yöntemi oluşturmanız gerekir. Uygulamanız gereken desenin temelleri aşağıdaki kodda gösterilmiştir:

worker.StartWorking += async (sender, eventArgs) =>
{
    try
    {
        await DoWorkAsync();
    }
    catch (Exception e)
    {
        //Some form of logging.
        Console.WriteLine($"Async task failure: {e.ToString()}");
        // Consider gracefully, and quickly exiting.
    }
};

İlk olarak, işleyicinin zaman uyumsuz bir işleyici olarak işaretlendiğine dikkat edin. Bir olay işleyicisi temsilci türüne atandığı için geçersiz bir dönüş türüne sahiptir. Bu, işleyicide gösterilen deseni takip etmeniz ve eşzamanlı olmayan işleyici bağlamından herhangi bir istisnanın fırlatılmasına izin vermemeniz gerektiği anlamına gelir. Bir görev döndürmediğinden, hata durumunu girerek hatayı bildirebilecek bir görev yoktur. Metot zaman uyumsuz olduğundan, metot istisna fırlatamaz. (asyncolan çağırma yöntemi yürütmeye devam eder.) Gerçek çalışma zamanı davranışı, farklı ortamlar için farklı şekilde tanımlanır. İş parçacığını veya iş parçacığının sahibi olan işlemi sonlandırabilir ya da işlemi kararsız bir halde bırakabilir. Bu olası sonuçların tümü son derece istenmeyen sonuçlardır.

Asenkron Görev için await ifadesini kendi try bloğunuzda sarmalamalısınız. Eğer bir görevin hatayla sonuçlanmasına neden olursa, hatayı günlüğe kaydedebilirsiniz. Bu, uygulamanızın kurtarılamadığını gösteren bir hataysa, programdan hızlı ve düzgün bir şekilde çıkabilirsiniz

Bu makalede .NET olay düzeninde yapılan önemli güncelleştirmeler açıklanmıştır. Çalıştığınız kitaplıklarda önceki sürümlerin birçok örneğini görebilirsiniz. Ancak en son desenlerin ne olduğunu da anlamanız gerekir. Örneğin tamamlanmış kodunu Program.cs görebilirsiniz.

Bu serideki bir sonraki makale, tasarımlarınızda delegates ve events kullanmayı ayırt etmesine yardımcı olur. Bunlar benzer kavramlardır ve bu makale programlarınız için en iyi kararı vermenizi sağlar.

sonraki