Asenkron ASP.Net Web Uygulamaları

05 Ocak 2016 4 dk okuma süresi 170 okunma

Öncelikle kavram karmaşasını önlemek istiyorum. Çünkü asenkron çalışma ile multi-thread aynı şeyler değildir ve nedense hep karıştırılır.

Asenkron yazılan metodlar tek thread üzerinde de çalışabilir. Asenkron programlamanın mantığı farklı thread'lerde çalışmak değil, verilen işleri parçalayıp ayna anda birden fazla işin yapılabilmesini sağlamaktır. Windows, windows store veya windows phone uygulamalarında asenkron kullanımın amacı uygulamanın (UI - user interface) responsive olması yani yapılan isteklere her zaman cevap verebilir olmasıdır. Basitçe açıklamak gerekirse asenkron kullanılmadığında uygulama yapılan isteklere cevap vermez ve uygulama istek bitene kadar geçici olarak donar. Bunun önüne geçmek için asenkron metodlar kullanılır.

Responsive olmayan uygulamalar
Responsive olmayan uygulamalar

Fakat web uygulamalarında durum bundan biraz farklıdır. Web uygulamalarında amaç responsive olması değil ölçeklenebilirliktir, çünkü web tarafında senkron çalışma bir istek bitmeden diğerine geçilmeyeceği demektir ve buna göre de bazı işlemler uzun sürebilir. Bu nedenle aynı anda birkaç iş yapabilmek önemlidir. Web tarafında asenkron kullanımı bize ölçeklenebilir bir web uygulaması sunar. Tabi yine dikkali kullanılmalıdır çünkü HTTP 503 hatalarına sebep olabilir.

Sanırım bu açıklama herkesin kafasında bir ışık yakmıştır. Şimdi asenkrona girmeden önce asp.net'in senkron metodları nasıl işelediğine bakmakta yarar var.

Tarayıcı sunucuya istek yaptığında ASP.Net *thread pool'dan bir tane *thread alır ve isteği bu thread'e atar. Bu yeni gelecek olan isteği thread tamamlanıncaya kadar bloklar ve istek tamamlanınca thread thread pool'a geri döner yeni gelen istek işleme alınır.

Aşağıdaki resim daha iyi anlamanıza yardımcı olabilir.

Asenkron çalışma mantığı
Asenkron çalışma mantığı

İlk kısımda senkron bir şekilde 3 işin yapıldığını görüyoruz. İlk olarak yeşil, sonra mavi ve turuncu. Herşey sırasında gidiyor. En alt resimde ise asenkron gidiş gösteriliyor. İlk olarak yeşil başlıyor ve işlemin bitip bitmediği bilinmeden mavi işlem görmeye başlıyor. Mavi devam ederken yeşil tamamlanıyor ve turuncu başlıyor ve bitiyor, hemen sonrasında ise mavi işlemini bitiriyor. Resimde de gördüğünüz gibi zaman kısalıyor.

Asenkrondaki önemli nokta şudur; yapılan isteğe atanılan thread asenkron işlem devam ederken işlemin bitip bitmediğine bakmadan thread pool'a geri döner ve o istek ile bir bağlantısı kalmaz. Bu durumda işlemin bitip bitmediği kendi geri dönüşü (bu geri dönüş database veya webapi üzerinden olabilir) ile belli olur. İşlem bittikten sonra geri dönüş thread pool'a tekrar istek yapar ve ASP.Net yine thread'lerden birisini geri dönüş için bu işleme atar. Bu şekilde işlemlerin devam ettiğini düşünürseniz aynı anda birden fazla işlemin başladığını ve daha kısa sürelerde işlemlerin bittiğini tahmin edebilirsiniz. Bu olayda istekler tek bir thread üzerinden de gidebilir birden fazla thread üzerinden de gidebilir.

Basit bir örnek kod yazmak gerekirse; aşağıdaki kod mvc'de action'a _List isimli modeli döndürüyor. Asenkron metod'ta istekler birbirini beklemeden çalışırken diğerinde birbirini bekleyerek çalışır. Yani senkron'da ilk olarak roller, sonra kullanıcılar ve sonrasında kullanıcı yetkileri sıralı bir şekilde listelenirken, asenkron metod'ta birbirinden bağımsız şekilde listelenebilir.

public class _List 
{
    public IEnumerable<Roller> Roller { get; set; }
    public IEnumerable<Kullanicilar> Kullanicilar { get; set; }
    public IEnumerable<KullaniciYetkileri> KullaniciYetkileri { get; set; }
}
// Asenkron metod
public async Task<ActionResult> Index()
{
    var model = new _List
    {
        Roller = db.Roller.ToListAsync(),
        Kullanicilar = db.Kullanicilar.ToListAsync(),
        KullaniciYetkileri = db.KullaniciYetkileri.ToListAsync()
    };
    return View(model);
}
// Senkron metod
public ActionResult Index()
{
    var model = new _List
    {
        Roller = db.Roller.ToList(),
        Kullanicilar = db.Kullanicilar.ToList(),
        KullaniciYetkileri = db.KullaniciYetkileri.ToList()
    };
    return View(model);
}


* thread pool: Arka planda belirli işleri yapmak üzere planlanmış görevlerin birden fazla thread'e bölünmesi ve bunların asenkron işlerini yöneten yapı. (görev havuzu, işlem havuzu da denebilir.)

* thread: görev veya işlem.


Daha detaylı öğrenmek için Stephan Cleary'nin " Async Programming : Introduction to Async/Await on ASP.NET" başlıklı msdn yazısını okuyabilirsiniz.

Yazılarıma abone olmak ister misiniz?
Spam yapılmaz, sadece bildirim amaçlıdır. İstediğiniz zaman abonelikten çıkabilirsiniz.
İlginizi çekebilecek diğer yazılar.
VS2015'in 3. update'ini yaptıktan sonra asp.net core web uygulaması yaratmak istediğimde şu şekilde bir hata ile karşılaştım. "Exception : The system cannot find the file specified. (Exception from HRESULT: 0x80070002)". Çözümü oldukça basit.

Entity framework code first kullanıyorsanız ve inheritance yapıp yeni bir class yarattığınızda bunun gibi bir hata alırsınız. Bunun nedeni fluent api'nin inheritance yapılan class ile ana class'ın map yapmaya çalışması ve ilgili kolonu veritabanında bulamamasıdır. Çözümü ise inherit olmuş class'a [NotMapped] DataAnnotations attribute'unu eklemek.

Asp.Net Mvc ile recursive nasıl yazılır, @helper veya HtmlHelper kullanarak recursive fonksiyon yazmak, Asp.Net MVC View recursive fonksiyon nasıl yazılır?