C# Asynchronous Programming (Asenkron Programlama)

Merhaba arkadaşlar,

Bu yazımda C# Programlama Kılavuzu adı altında başladığım C# serimin son konusu olan Asenkron Programlama hakkında elde ettiğim bilgileri paylaşıp örnekler üzerinde pekiştiriyor olacağız. Öncelikle daha önceden de bahsettiğim ve bana referans olan “Her Yönüyle C#” kitabı ve yazarı Sefer Algan’a teşekkürlerimi sunarım 🙂 C# yazılarımda referans olarak ağırlıklı olarak bu kitabı aldım ve kafama yatmayan bazı yerleri 🙂 Microsoft dokümanından ve diğer kaynaklardan yararlandım. O yüzden C# programlama dilini ve .Net Sınıf Kütüphanesini temel düzeyde ana hatlarıyla öğrenebileceğimiz güzel bir C# serisi olduğunu düşünüyorum.

Hadi serinin son konusu olan Asenkron Programlama‘ya başlayalım.

Bu yazıda bahsedilecek konular

  • Asenkron Programlama
  • async ve await anahtar kelimeler
  • Caller Information Attribute (Nitelik)
  • C# 6.0 ile ilgili güncelleme notu

Giriş

Asenkron Programlamaya geçmeden önce asenkron kelimesinin anlamına bakalım;

Asenkron, başlama ve sona erme zamanları ayrı olan, aynı zamanda olmayan (olgular, olaylar). Asenkron programlama ise işleri parçalara bölüp bütün işleri aynı anda sürdürülmesini sağlayan bir davranış diyebiliriz. Yani programlama yaparken yazdığımız kod sürdürülürken aynı program içerisinde farklı işleri de sürdürülebilir.

.NET 1.0 sınıf kütüphanesinden bu yana eş zamanlı programlamayı ya da eş zamanlı olmayan programlamayı desteklemekteydi. C# 5.0 sürümünden önce IAsyncResult arayüzünden türetilen sınıflar yardımcı oluyordu. C# 5.0 sürümünden sonra asenkron işlemlerin daha kolay ve anlaşılır şekilde yapabiliyoruz.

Yeni yapının kalbine async ve await anahtar kelimeler bulunmaktadır. Bu iki anahtar kelime eş zamanlı metot yazma kolaylığında eş zamanlı olmayan metot yazmamıza olanak sağlıyor. async await anahtar kelimeler .Net 4.0 ile birlikte kullanılıyor. Bu iki anahtar kelimenin arka yapısında Task kullanılmaktadır.

async ve await Anahtar Kelimeler

async ve await anahtar kelimeler sayesinde C# derleyicisi kodun neresine müdahale edeceğini bilir. Derleyici bu iki anahtar kelimeyi gördüğü yerde derleme zamanında kodun asenkron yapıya dönüştürür.

  • async anahtar kelime derleyiciye metot içinde await anahtar kelime kullanılacağını bildirir.
  • async anahtar kelime kullanıldığı metotlarda await anahtar kelime kullanılmaz ise kodun yapısında bir değişiklik olmayacaktır
  • bir metodun async olarak işaretlenebilmesi için metodun geri dönüş değeri mutlaka void, Task veya Task<TResult> tipinde olmalıdır.
  • async ile işaretlenen metotlara ref veya out anahtar kelimeleri kullanılamaz.
  • async anahtar kelime derleyiciye kullanıldığı yerde asenkron işlem olacağını bildirir. await‘ten sonra kullanılacak metotların geri dönüşü mutlaka Task veya Task<TResult> olmalıdır.
  • await anahtar kelime async ile işaretlenmiş metotlar dışında kullanılamazlar

async ve await anahtar kelimelerin nasıl kullanılacağını anlamak adına hem eş zamanlı (senkron) hem de eş zamansız (asenkron) örnek yaparak bu anahtar kelimeleri örnek üzerinde pekiştirelim

Yukarıdaki örnekte sürekli BackgroudMetohd metodunun ürettiği değeri Console uygulamasında ekrana [BackgroundMethod] yazdığını görüyoruz. Senkron bir şekilde bu işlemi yaptığımız için Thread için işler parçalara bölünmedi ve haliyle ilk metodun bitmesi bekleniyor. BackgroudMetohd metodunun içinde sonsuz bir döngü olduğu için ondan sonra gelen metotlar çalışmayacaktır.

Şimdi bu yapıyı asenkron bir yapıya çevirelim ve sonsuz döngüde çalışan BackgroudMetohd metodu ile onun ardında çalışacak metotları aynı anda sürdürmesini sağlayalım.

Yukarıdaki örnekte Thread bloklanmadan hem BackgroundMethod işlemi sürdürülüyor hem de diğer işlerde paralelinde sürdürülüyor.

Async son eki ile biten metotlar IAsyncResult arayüzünden türemiş sınıflardır. Bu sayede hem Task alt yapısı ile çalışabilmesi hem de geriye dönük uyumluluk sağlanmış oluyor.

Not: Genelde asenkron programlama ile multi-thread programlama aynı şey olarak düşünülür. Bu her zaman için doğru bir bilgi değildir.

Caller Information Attribute (Nitelik)

Bazen geliştirdiğimiz uygulamalarda kimin hangi metodu veya özelliğini çağırdığı bilgisine ihtiyaç duyarız. Bu bilgiler özellikle büyük uygulamalarda bakım yapılabilirliğini (maintainability) açısından çok önemlidir. Çağrılan bilgiler uygulamadaki bug‘ların tespiti, hataların kaydedilmesi, performans ölçümü gibi konular için bazen hayati önem taşır.

C# 5.0’dan önce bu bilgileri elde etmek için System.Diagnostic isim alanı içerisinde bulunan StackTrace ve StackFrame sınıfları kullanılarak çalışma zamanında (run-time) elde edilebiliyordu. Ancak bu yapı kullanılarak call-stack bilgisini kullandıkları için performans sorunlarına sebep oluyordu.

Caller Information nitelikleri bu bilgilere ulaşabilmek için daha kolay ve okunaklı bir alternatif sunuyor.

Caller Information nitelikleri, metotların sadece opsiyonel parametrelerinde kullanılır. Bu işlemler için üç adet nitelik vardır;

  • [CallerMemberName]: çağrımı yapan metot veya özellik için bilgi verir
  • [CallerFilePath]: çağrımı yapanın kaynak kodunu içeren dosya yolu bilgisini verir
  • [CallerLineNumber]: çağrımı yapan kodun satır numarası bilgisini verir

Caller Information niteliklerinin kullanımı ile ilgili örnek yapalım;

C# 6.0 ile ilgili Güncelleme Notu

C# 5.0 ile birlikte await kullanımı catch bloklarında kullanılamıyordu. Buna göre herhangi bir catch bloğunda normal bloklar gibi await kullanılabilmektedir.

Bu yazımla C# programlama dili ve .Net sınıf kütüphanesini daha iyi anlamak için giriştiğim blog serimin sonuna gelmiş bulunmaktayım. Geriye dönük baktığım zaman gerek zaman zaman zorlandığım gerekte keyif aldığım bu serimin bitirmenin mutluluğu içindeyim açıkçası 🙂 Bundan sonra edindiğim bu bilgileri kullanarak kodlama yaparken zevkli işler yapacağıma inanıyorum 🙂

Bu yazımda Asynchronous Programming (Asenkron Programlama) hakkında elde ettiğim bilgileri paylaşmaya çalıştım. Umarım faydalı olmuştur.

Bir sonraki yazımda görüşmek üzere 🙂

Kaynaklar:

Her Yönüyle C# 7.0, Sefer Algan, Pusula Yayincilik,

https://docs.microsoft.com/tr-tr/dotnet/csharp/programming-guide/concepts/async/

Leave a Comment