async/await ile Asenkron Programlama

22 Oca

Asenkron işlmeler

Asenkron çalışma prensibi, yürütülen süreçlerin uzun sürmesinden dolayı, yürütülmesi gereken diğer süreçlerin beklemeden çalışmasına devam edebilmesi için geliştirilmiştir. Bazen wab ortamındaki bir kaynağa erişip istekte bulunmak ve cevap almak uzun sürebilmektedir. Senkron çalışma prensibinde örneğin bir web kaynağından cevap gelene kadar sıradaki işlem yürütülmez.  Ancak asenkron süreçlerde uzun sürebilecek işlemler farklı bir görev olarak tanımlanarak çalıştırılır ve sıradaki işleme geçilir. Böylece uzun süren işlemler arka planda farklı görevler olarak çalışmaya devam eder.

Asenkron progamlama genellikle Windows Forms, WPF ve Silverlgiht gibi uygulamalarda, uzun süren işlemlerde form arayüzlerinin kullanıcıya cevap verememesi gibi sorunların çözümü için kullanılabilir. Grafik arayüzlü(UI) uygulamalarda tüm grafiksel işlemler tek bir thread üzerinden yürütülür. Örneğin veritabanından yüklüce bir veriyi çekip Datagrid gibi bir nesneye yüklemeye çalıştığımızda thread önce veriyi almalıdır ki aynı thread daha sonra aldığı veriyi Datagrid nesnesine bağlayabilsin. Tabi bu süre içerisinde Formu sürüklemek yada Form üzerindeki diğer bileşenlere ulaşmak da engellenmiştir.

Diğer taraftan dosya işlemleri, resim işlemleri, WCF, soket uygulamaları gibi işlemler de asenkron süreçlerin işletilmesine ihtiyaç duyulabilecek işlemlerdir.

.Net Framework 4.5 öncesinde asenkron API’leri şu sırayla gelişmiştir:

  1. Asynchronous Programming Model (APM)
  2. Event based Asynchronous Pattern(EAP)
  3. Task Parallel Library(TPL) tabanlı, Task-based Asynchronous Pattern(TAP).

Bu yazıda üzerinde durduğumuz konu da TAP modeli ile asenkron programlama seçeneğidir.

TAP modeli ile asenkron programlamanın tam merkezine oturmuş olan “async” ve “await” anahtar kelimelerini inceleyerek devam edelim. Bu iki sihirli kelime, senkron çalışan bir süreci asenkron hale çevirebilmek için kullanılırlar.

Anahtar kelimelerin (async/await) kullanımı

“async” anahtar kelimesi, kullanıldığı metod içerisinde “await” anahtar kelimesinin etkinleştirilmesi  için kullanılır. “async” anahtar kelimesinin kullnaılmadığı metodlarda “await” anahtar kelimesi çalışmaz. Yani “async” anahtar kelimesinin kullanıldığı metodu asenkron hale çeviren bir sihiri yoktur.

Async kullanılan metodlar tıpkı diğer metodlar gibi çalıştırılır. Her hangi bir farkı yoktur. Ta ki derleyici “await” ile karşılaşana kadar işlemler senkron olarak işletilir. İşlemler Thread pool içerisinde bir thread ile yürütülür. “async” ve “await” kelimelerinin kullanımı aşağıdaki gibidir.

private async void download(string url)
{
    var down = await Downloader.DownloadString(url);
}

Yeri gelmişken Thread akışını şu şekilde inceleyebiliriz.

Main metod ve download metodu içerisinde “await” kelimesine kadar olan işlemler Thread 1 ile gerçekleştirilmektedir. “await” kelimesinden sonra işlemler Thread Pool içerisinden başka bir thread olan Thread 3 ile yürütülmüştür.

“await” kelimesinin kullanıldığı yerdeki işlem asenkron şekilde yürütülür. “await” kelimesi matematiksel operatorler gibi düşünülebilir. “await” anahtar kelimesi sadece await edilebilir metodlar ile kullanılabilir. Her metodun önüne “await” klimesini kullanamayız, sadece await için uygun metodlar için bu kelimeyi kullanabiliriz.

Yukarıdaki örnekte System.Threading.Tasks.Task tipine ait Run metodu (awaitable) şeklinde düzenlenmiştir. Artık DownloadStringTaskAsync metodu “await” anahtar kelimesi ile kullanılabilir.

Asenkron metodlar için Unit Test

Yukarıda yazılan örnek metod için bir de unit test yazacak olursak.

Eğer “async/await” kelimelerini unit testler yazarken de kullanmalıyız. Aksi taktirde compailer, Downloader.DownloadString() metodu için bir awaitable Task tipi döndüreceğinden metodumuz testten geçemeyecektir.

Bu yazıda kullanılan örnek kodları barındıran uygulamaya SkyDrive üzerinden bu linkten ulaşabilirsiniz.

Tekrar görüşmek dileğiyle.