await ile Seri ve Paralel İşlemler

   Sunumlarım sonrasında asenkron programlama ile uygulama geliştirenlerle yaptığım konuşmalarda gördüğüm bir yanılgıyı buradan düzeltmek isterim. Pek çok yazılım geliştirici asenkron programlama ile uygulamalarında artık her işin paralel yapılarak zaman kazanabileceklerini düşünmekte. Bu düşünce hem de doğru, hem yanlış aslına bakarsanız. Yanlış; çünkü geliştirilen asenkron uygulama varsayılan olarak paralel çalışmaz. Doğru; çünkü istersek asenkron uygulamamızın paralel çalışmasını sağlayabiliriz. Konunun daha rahat anlaşılabilmesi adına aşağıdaki örnek kod parçacığını ele alalım;

string icerik1 = await new WebClient().DownloadStringTaskAsync("http://www.enterprisecoding.com/");
string icerik2 = await new WebClient().DownloadStringTaskAsync("http://www.enterprisecoding.com/");
string icerik3 = await new WebClient().DownloadStringTaskAsync("http://www.enterprisecoding.com/");

LinkleriListele(icerik1);
LinkleriListele(icerik2);
LinkleriListele(icerik3);

   Bu basit kodda arayüzü kilitlemeden ayrı iş parçacıklarında enterprisecoding.com web sitesi ana sayfası içeriği 3 defa getirilmekte ve daha sonrada senkron olarak gelen içerikte yer alan linkler listelenmekte. Burada dikkat edilmesi gereken nokta, bu kodda yer alan sayfa içeriklerinin getirilmesi işlerinin arayüz iç parçacığını meşgul etmeden ayrı iş parçacığında yapılıyor olmasına karşın paralel değil seri şekilde yapılıyor olmasıdır. icerik1’in getirilmesini takiben icerik2, daha sonrasında da icerik3 asenkron olarak getirilmekte, kodun geri kalanı ise bu iş kalemlerinin sırasıyla bitmesi sonrası senkron olarak tamamlanmaktadır. ilk 3. satırda yer alan await (asynchronous wait – asenkron bekleme) derleyiciye kodun bu doğrultuda oluşturulması konusunda ipucu vermektedir. Buradaki önemli ve bilinmesi gereken nokta; asenkron işin await ile başlatılmıyor olmasıdır. Await sadece asenkron olarak başlatılan içerik indirme işini bitene kadar kodun ayrı bir iş parçacığında bekletilerek işin bitmesi sonrasında devam etmesini sağlamaktadır. C# 4.0 ile birlikte gelen Task Parallel Library (TPL)’ye aşına olanlarınızın bileceği gibi işlem aslında DownloadStringTaskAsync fonksiyonu çağrıldığı anda başlamış olacaktır. Fonksiyon çağrısı sonrasında geriye dönen Task<string> türündeki iş nesnesince gerçekleştirilen iş await ile tamamlanana kadar beklenilmek üzere işaretlenmektedir.

    Bu bilgiler ışığında, kodu aşağıdaki şekilde revize etmemiz sonrasında artık her 3 içerik indirme işi de paralel olarak gerçekleşecektir;

Task<string> task1 =  new WebClient().DownloadStringTaskAsync("http://www.enterprisecoding.com/");
Task<string> task2 = new WebClient().DownloadStringTaskAsync("http://www.enterprisecoding.com/");
Task<string> task3 = new WebClient().DownloadStringTaskAsync("http://www.enterprisecoding.com/");
LinkleriListele(await task1);
LinkleriListele(await task2);
LinkleriListele(await task3);

   Her iki kod parçasını da inceleyecek olursak aradaki en önemli farkın await’in bulunduğu yer olduğunu rahatlıkla görebilirsiniz. ilk 3 satır, önceki örnekte olduğu gibi, web sayfası içeriğinin indirilmesini başlatacaktır; fakat öncekinden farklı olarak asenkron olarak gerçekleşen bu işlerin tamamlanması await kullanılmaması nedeniyle bu satırlarda beklenmeyecektir. Bu işlerin tamamlanmasının ayrı bir iş parçacığında beklenmesi LinkleriListele fonksiyonlarının çağrıldığı son 3 satırda yapılacaktır. Önceki kodumuzdan farklı olarak işler başlamak için bir öncekinin bitmesini beklemeyeceğinden dolayı da kodumuzun işleyişi 4. satıra geldiğinde 3 iş çoktan paralel olarak başlamış olacaktır. Tabi ki içeriğin gelmesi sorasında işlenmesi önceki örnekteki gibi ardıl olarak yapılmaya devam edecektir.

    Gördüğünüz gibi C# async ve await yardımıyla asenkron işlemlerimizi oldukça kolay yapabiliyor olmanın dışında, bu işlerin paralel ya da seri şekilde yapılmasını da bir o kadar kolay kontrol edebiliyoruz.

Fatih Boy

Ankara'da yaşayan Fatih, bir kamu kurumunda danışman olarak çalışmaktadır. ALM süreçleri, kurumsal veri yolu sistemleri, kurumsal altyapı ve yazılım geliştirme konularında destek vermektedir. Boş zamanlarında açık kaynak kodlu projeler geliştirmeyi ve bilgisini yazdığı makalelerle paylaşmayı seven Fatih, aynı zamanda Visual C# ve Visual Studio teknolojileri konusundan Microsoft tarafından altı yıl üst üste MVP (En Değerli Profesyonel) ödülüne layık görülmüştür. İş hayatı boyunca masaüstü uygulamaları, web teknolojileri, akıllı istemciler gibi konularda Asp.Net, Php, C#, Java programlama dilleri ve MySql, MsSql ve Oracle gibi veritabanı yönetim yazılımları ile çalışmıştır. İngilizce ve Türkçe olarak yayınlanan makalelerini gerek İngilizce bloğunda, gerekse de Türkçe bloğunda bulabileceğiniz gibi web sitesinden de açık kaynak kodlu geliştirdiği yazılımlarına ulaşabilirsiniz. vCard - Twitter - Facebook - Google+

Bir Cevap Yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir