MVC5 ile eşzamansız kullanmanın avantajı nedir?


120

Arasındaki fark nedir:

public ActionResult Login(LoginViewModel model, string returnUrl)
{
    if (ModelState.IsValid)
    {
        IdentityResult result = IdentityManager.Authentication.CheckPasswordAndSignIn(AuthenticationManager, model.UserName, model.Password, model.RememberMe);
        if (result.Success)
        {
            return Redirect("~/home");
        }
        else
        {
            AddErrors(result);
        }
    }
    return View(model);
}

ve:

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
    if (ModelState.IsValid)
    {
        IdentityResult result = await IdentityManager.Authentication.CheckPasswordAndSignInAsync(AuthenticationManager, model.UserName, model.Password, model.RememberMe);
        if (result.Success)
        {
            return Redirect("~/home");
        }
        else
        {
            AddErrors(result);
        }
    }
    return View(model);
}

MVC kodunun artık zaman uyumsuz olduğunu görüyorum ama fark nedir. Biri diğerinden çok daha iyi performans veriyor mu? Birindeki sorunlarda hata ayıklamak diğerinden daha mı kolay? Uygulamamın Async eklenmesi için diğer denetleyicilerde değişiklik yapmalı mıyım?


Çoğu durumda,
MVC'de

1
@ChrisMarisic - En ciddi olanlardan biri: ReaderWriterLock veya diğer senkronizasyon ilkellerinden herhangi birini kullanamazsınız (Semaphore hariç).
Quarkly

Yanıtlar:


170

Zaman uyumsuz eylemler yalnızca uzak sunucu çağrıları gibi G / Ç bağlantılı işlemler gerçekleştirirken kullanışlıdır. Zaman uyumsuz çağrının yararı, G / Ç işlemi sırasında ASP.NET çalışan iş parçacığının kullanılmamasıdır. İşte ilk örnek şu şekilde çalışıyor:

  1. Bir istek eyleme ulaştığında, ASP.NET iş parçacığı havuzundan bir iş parçacığı alır ve onu yürütmeye başlar.
  2. IdentityManager.Authentication.CheckPasswordAndSignInYöntemi çağrılır. Bu bir engelleme çağrısıdır -> tüm çağrı sırasında işçi iş parçacığı tehlikeye atılır.

Ve işte ikinci aramanın işleyişi:

  1. Bir istek eyleme ulaştığında, ASP.NET iş parçacığı havuzundan bir iş parçacığı alır ve onu yürütmeye başlar.
  2. IdentityManager.Authentication.CheckPasswordAndSignInAsyncHemen döndüren olarak adlandırılır. Bir G / Ç Tamamlama Bağlantı Noktası kaydedilir ve ASP.NET çalışan iş parçacığı iş parçacığı havuzuna bırakılır.
  3. Daha sonra işlem tamamlandığında, G / Ç Tamamlama bağlantı noktasına sinyal verilir, görünümü geri döndürmeyi bitirmek için iş parçacığı havuzundan başka bir iş parçacığı çekilir.

İkinci durumda görebileceğiniz gibi ASP.NET çalışan iş parçacıkları yalnızca kısa bir süre için kullanılır. Bu, havuzda diğer isteklere hizmet vermek için daha fazla iş parçacığı olduğu anlamına gelir.

Sonuç olarak, zaman uyumsuz eylemleri yalnızca içinde gerçek bir zaman uyumsuz API'niz olduğunda kullanın. Eşzamansız bir eylemin içinde engelleme çağrısı yaparsanız, tüm faydasını öldürürsünüz.


Bağlam senkronizasyonuna ne dersiniz? Bu, eşzamansız eylemleri hiç kullanmak istemeyeceğiniz bir ek yük olmayacak mı? "Eşzamansız olarak yürütülen bir eşzamansız yöntemin ek yükü, tamamen SynchronizationContext.Post kullanarak iş parçacıkları değiştirmesi gerekip gerekmediğine bağlıdır. Eğer öyleyse, ek yük, devam ederken gerçekleştirdiği iş parçacığı anahtarı tarafından yönetilir. Bu, mevcut SynchronizationContext'in yaptığı anlamına gelir büyük bir fark." (Async in C # 5.0, 2012, Alex Davies)
annemartijn

1
@Darin Ana konuyu yayınlamak neden bu kadar önemli? Konu sınırlı mı?
Omtechguy

1
@Omtechguy daha iyi bir çözüm, ASP.NET dışı istekleri bir CDN'ye taşımaktır. Basit bir CDN, yalnızca javascript ve resimleriniz gibi fiziksel dosyalar için alt alan ve ayrı uygulama havuzu kullanır. Alternatif olarak dosyalar için NgineX / Lighttpd / Apache'yi veya Akamai (CDN için kral ama en pahalısı) gibi üçüncü taraf bir hizmeti kullanabilirsiniz
Chris Marisic

Hala kafam karışık. Ne zaman CheckPasswordAndSignInAsyncdenir, ASP.NET Öyle, değil parçacığı havuzundan başka iş parçacığı alır ve onu çalıştırmaya başlar? Olmazsa, nerede checking password procedureidam edilir?
KevinBui

2

Normalde, tek bir HTTP isteği tek bir iş parçacığı tarafından işlenir ve bir yanıt dönene kadar bu iş parçacığını havuzdan tamamen kaldırır. TPL ile bu kısıtlamaya bağlı değilsiniz. Gelen herhangi bir istek, havuzdaki herhangi bir iş parçacığı üzerinde yürütülebilecek bir yanıtı hesaplamak için gereken her hesaplama birimiyle bir devamı başlatır. Bu modelle, standart ASP.Net'ten çok daha fazla eşzamanlı isteği işleyebilirsiniz.

Ortaya çıkacak yeni bir görev olup olmadığı ve beklenip beklenmemesi gerektiği. Her zaman yaklaşık 70 ms olan bu 70 ms'yi düşünün. maks. herhangi bir yöntem çağrısının alması gereken süre. Daha uzunsa, kullanıcı arayüzünüz büyük olasılıkla çok duyarlı hissetmeyecektir.


0

Başlangıçta çok sayıda eşzamanlı istek gören veya ani bir yükü olan (eşzamanlılığın aniden arttığı) web uygulamalarında, bu web hizmeti çağrılarını eşzamansız hale getirmek uygulamanızın yanıt verebilirliğini artıracaktır. Eşzamansız bir isteğin işlenmesi eşzamanlı bir istekle aynı süreyi alır. Örneğin, bir istek, tamamlanması iki saniye gerektiren bir web hizmeti çağrısı yaparsa, istek eşzamanlı veya eşzamansız olarak gerçekleştirilsin iki saniye sürer. Ancak, eşzamansız bir çağrı sırasında, iş parçacığının ilk isteğin tamamlanmasını beklerken diğer isteklere yanıt vermesi engellenmez. Bu nedenle, zaman uyumsuz istekler, uzun süre çalışan işlemleri çağıran birçok eşzamanlı istek olduğunda istek kuyruğunu ve iş parçacığı havuzunun büyümesini engeller.


Aspnet uygulamanız büyük ölçüde diğer web sunucularına yapılan çağrılardan oluşuyorsa, büyük ölçüde bir 'ağ geçidi' / 'proxy' gibi davranıyorsunuzdur ve zaman uyumsuz bu amaç için kullanışlıdır.
Chris Marisic
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.