ASP.NET MVC'de Async Denetleyicilerini ne zaman kullanmalıyım?


216

ASP.NET MVC zaman uyumsuz eylemleri kullanarak bazı endişeleri var. Ne zaman uygulamalarıma performansını artırmak etmez ve ne zaman öyle değil ?

  1. ASP.NET MVC'de her yerde zaman uyumsuz eylem kullanmak iyi midir?
  2. Beklenebilir yöntemler ile ilgili: Bir veritabanını sorgulamak istediğimde async / await anahtar sözcüklerini kullanmalı mıyım (EF / NHibernate / other ORM aracılığıyla)?
  3. Kaç kere de uyumsuz veritabanını sorgulamak için bekliyoruz anahtar kelimeler kullanabilirsiniz biri tek eylem yöntemi?

Yanıtlar:


109

Bir eylemin birkaç bağımsız uzun çalışan işlem gerçekleştirmesi gerektiğinde eşzamansız eylem yöntemleri yararlıdır.

AsyncController sınıfı için tipik bir kullanım, uzun süredir çalışan Web hizmeti çağrılarıdır.

Veritabanı çağrılarım zaman uyumsuz olmalı mı?

IIS iş parçacığı havuzu genellikle bir veritabanı sunucusundan daha fazla eşzamanlı engelleme isteğini işleyebilir. Veritabanı darboğazsa, zaman uyumsuz çağrılar veritabanı yanıtını hızlandırmaz. Kısıtlama mekanizması olmadan, zaman uyumsuz çağrılar kullanarak bunalmış bir veritabanı sunucusuna daha fazla iş göndermek, yükün daha fazlasını veritabanına kaydırır. DB'niz darboğazsa, zaman uyumsuz çağrılar sihirli madde işareti olmaz.

Sen gerektiğini de bakabilirsiniz 1 ve 2 referans

@PanagiotisKanavos yorumlarından türetilmiştir:

Dahası, asenkron paralel demek değildir. Eşzamansız yürütme, karmaşık bir iş parçacığı iş parçacığı iş parçacığının karmaşıklığı veya performans maliyeti olmaksızın harici bir kaynak için engellemesini engeller. Bu, aynı IIS makinesinin daha hızlı çalışacağı için değil, daha fazla eşzamanlı istekleri işleyebileceği anlamına gelir.

Ayrıca, çağrıları engellemenin CPU yoğunluklu bir spinwait ile başladığını da düşünmelisiniz. Stres zamanlarında, çağrıları engellemek, artan gecikmeler ve uygulama havuzu geri dönüşümü ile sonuçlanacaktır. Zaman uyumsuz çağrılar bundan kaçınır


27
Zaman uyumsuzluk, IIS ve veritabanı ile ilgili olarak, blog gönderisi son derece eskidir ve burada çizilen sonuçlar yanlıştır. IIS, veritabanından çok daha büyük bir yük sunucuya sunmak zorundadır , threadpool iş parçacıkları sınırlıdır ve uzun bir istek kuyruğu 500'e yol açabilir. G / Ç'yi beklerken iş parçacığını serbest bırakan her şey yararlıdır. Bağlantılar bile OP'nin ne istediğiyle ilgili değil . Aslında aynı yazarlar nerede olursanız olun zaman uyumsuz DB yöntemleri kullanmanız gerektiğini yazdı
Panagiotis Kanavos

30
Dahası, asenkron paralel demek değildir. Eşzamansız yürütme, karmaşık bir iş parçacığı iş parçacığı iş parçacığının karmaşıklığı veya performans maliyeti olmaksızın harici bir kaynak için engellemesini engeller. Bu , aynı IIS makinesinin daha hızlı çalışacağı için değil, daha fazla eşzamanlı istekleri işleyebileceği anlamına gelir .
Panagiotis Kanavos

5
Ayrıca, çağrıları engellemenin CPU yoğunluklu bir spinwait ile başladığını da düşünmelisiniz. Stres zamanlarında, çağrıları engellemek, artan gecikmeler ve uygulama havuzu geri dönüşümü ile sonuçlanacaktır. Eşzamansız aramalar sadece bundan kaçınır
Panagiotis Kanavos

1
Bu kabul edilen cevap ve bu yüzden çoğu insan için en üstte olduğu için, asenkron ile hiçbir ilgisi olmayan yürütme süreleri ve paralel koşma ile ilgili ikinci birinci paragrafı kaldırmak akıllıca olabilir. Ben bir not sonunda orada olduğunu biliyorum ama o olduğu oldukça yanıltıcı.
Rob

1
Eşzamansız yürütme, bir iş parçacığını yalnızca uygulamanın en alt kısmına kadar tam olarak eşzamansız olduğu durumlarda serbest bırakır ve hazırlığı işaret etmek ve bağlamı değiştirmek ve sonucu işlemek için yeni bir iş parçacığını döndürmek için bazı geri çağrı mekanizmaları kullanır. Yani, hangi durumlarda bu bağlam değiştirme / yeni iş parçacığı oluşturma sadece tek bir iş parçacığında sonuçları beklemek daha verimli olduğundan emin değilim? Uzun süren web hizmeti çağrıları yine de kötü bir fikirdir, güvenilir bir arka plan hizmetine boşaltmayı ve müşterinin birkaç dakika, saat veya gün içinde gelebilecek sonuçları kontrol etmesini tercih ederim.
JustAMartin

229

Sen benim bulabilirsiniz yararlı konuda MSDN makalesine ; Bu makalede , ASP.NET'te ne zaman kullanılacağını değil, ASP.NET'te ne zaman kullanmanız gerektiğini açıklayan çok yer kapladım.asyncasync

ASP.NET MVC zaman uyumsuz eylemleri kullanarak bazı endişeleri var. Uygulamalarımın performansını artırdığında ve ne zaman değil.

İlk olarak, async/ awaitparçacıklarını serbest bırakmakla ilgilidir . GUI uygulamalarında, temel olarak GUI iş parçacığını serbest bırakmakla ilgilidir, böylece kullanıcı deneyimi daha iyi olur. Sunucu uygulamalarında (ASP.NET MVC dahil), esas olarak sunucunun ölçeklenebilmesi için istek dizisini boşaltmakla ilgilidir .

Özellikle :

  • Bireysel isteklerinizi daha hızlı tamamlayın. Aslında, (sadece bir teensy bit) daha yavaş tamamlayacaklar.
  • Bir tuşa bastığınızda arayana / tarayıcıya dönün await. awaittarayıcıya değil, yalnızca ASP.NET iş parçacığı havuzuna "verir".

İlk soru - ASP.NET MVC her yerde zaman uyumsuz eylem kullanmak iyi mi?

G / Ç yaptığınız her yerde kullanmanın iyi olduğunu söyleyebilirim. Bununla birlikte, mutlaka yararlı olmayabilir (aşağıya bakınız).

Ancak, CPU'ya bağlı yöntemler için kullanmak kötü . Bazen devs async, sadece Task.Runkontrolörlerini arayarak fayda sağlayabileceklerini düşünüyor ve bu korkunç bir fikir. Bu kod, başka bir iş parçacığı alarak istek iş parçacığını serbest bıraktığından, hiçbir faydası yoktur (ve aslında, ek iş parçacığı anahtarlarının cezasını çekiyorlar)!

Veritabanını sorgulamak istediğimde (EF / NHibernate / diğer ORM aracılığıyla) async / await anahtar sözcüklerini kullanmalı mıyım?

Mümkün olan her türlü yöntemi kullanabilirsiniz. Şu anda büyük oyuncuların çoğu destekliyor async, ancak desteklemeyen birkaç kişi var. ORM'niz desteklemiyorsa async, onu Task.Runveya benzeri bir şeyi sarmaya çalışmayın (yukarıya bakın).

Not I "dediniz olabilir kullan". Tek bir veritabanı arka ucuna sahip ASP.NET MVC'den bahsediyorsanız, (neredeyse kesinlikle) herhangi bir ölçeklenebilirlik avantajından yararlanamayacaksınız async. Bunun nedeni, IIS'nin tek bir SQL sunucusunun (veya diğer klasik RDBMS) örneğinden çok daha fazla eşzamanlı isteği işleyebilmesidir. Ancak, arka uç daha modern eğer, - SQL sunucu kümesi Azure SQL, NoSQL, vs - ve arka uç ölçeklenebilir ve sizin ölçeklenebilirlik darboğaz, IIS sonra size bir ölçeklenebilirlik parası alabilirsiniz async.

Üçüncü soru - Veritabanını bir tek eylem yönteminde eşzamansız olarak sorgulamak için kaç kez anahtar kelime bekleyebilirim?

İstediğiniz kadar. Ancak, birçok ORM'nin bağlantı başına bir işlem kuralı olduğunu unutmayın. Özellikle, EF her DbContext için tek bir işleme izin verir; bu işlem eşzamanlı veya eşzamansız olsun, doğrudur.

Ayrıca, arka ucunuzun ölçeklenebilirliğini tekrar unutmayın. SQL Server'ın tek bir örneğini vuruyorsanız ve IIS'niz zaten SQLServer'ı tam kapasitede tutabiliyorsa, SQLServer üzerindeki baskıyı iki katına çıkarmak veya üç katına çıkarmak size hiç yardımcı olmaz.


2
@seebiscuit: (uygun asenkron) G / Ç yaparken hiçbir iş parçacığı kullanılmaz. Daha ayrıntılı bir blog yazısı var.
Stephen Cleary

2
IIS ve tek bir SQL Server örneği kaç istekte bulunabilir? Bu numaraları nasıl bulabilirim?
MOD

1
@MOD: Konfigürasyon ve donanıma bağlıdır. Bu numaraları bulmanın tek yolu kendi sunucunuzda bir yük testi yapmaktır.
Stephen Cleary

1
@Flezcano: İşlemci üzerinde tam olarak çalışan yöntemler. Yani, G / Ç veya engelleme yapmazlar.
Stephen Cleary

1
Üzgünüm efendim ama SO anlamaya çalışıyorum bu 2 liner soruyu kabul olmaz alışkanlık. Ben aynı şey 1000 kullanıcı tarafından çağrılan 1 web api bitiş noktası varsa o zaman bu bitiş noktası mümkün olacak gibi bu şey için araştırma yaparken Bu bin istek sunucu her veya 1000 istek işlemek için zaman uyumsuz yapmak gerekir?
Öğrenme-Overthinker-Karışık

21

.NET MVC her yerde zaman uyumsuz eylem kullanmak iyidir?

Programlamada her zamanki gibi, duruma göre değişir . Belli bir yolda giderken her zaman bir değiş tokuş vardır.

async-awaithizmetinize eşzamanlı istekler alacağınızı bildiğiniz yerlerde parlar ve iyi ölçeklendirmek istersiniz . async-awaitÖlçeklendirme konusunda yardım nasıl ? Bir ağ çağrısı veya veritabanınıza isabet gibi eşzamansız bir GÇ çağrısını eşzamanlı olarak çağırdığınızda, isteğin tamamlanmasını bekleyen yürütme işleminden sorumlu olan geçerli iş parçacığı engellenir. Kullandığınızda async-await, çerçevenin sizin için bir IO çağrısı tamamlandıktan sonra yönteminizin kaldığı yerden çalışmaya devam etmesini sağlayan bir durum makinesi oluşturmasını sağlarsınız.

Dikkat edilmesi gereken bir nokta, bu durum makinesinin ince bir ek yükü olmasıdır. Bir yöntemi eşzamansız yapmak, uygulamanın daha hızlı yürütülmesini sağlamaz ve bu, birçok insanın anlaması için önemli bir faktör ve bir yanlış anlamadır.

Kullanırken göz önünde bulundurulması gereken başka bir şey async-await, bunun tamamen eşzamansız olmasıdır , yani eşzamansız olarak tüm çağrı yığınınıza nüfuz ettiğini göreceksiniz. Bu, eşzamanlı API'ları ortaya çıkarmak istiyorsanız, zaman uyumsuzluk ve senkronizasyon çok iyi karışmadığı için genellikle belirli bir miktarda kodu çoğaltırsınız .

Veritabanını sorgulamak istediğimde (EF / NHibernate / diğer ORM aracılığıyla) async / await anahtar sözcüklerini kullanmalı mıyım?

Zaman uyumsuz G / Ç çağrılarını kullanma yolunda ilerlemeyi seçerseniz, evet, async-await daha fazla modern veritabanı sağlayıcısı TAP (Görev Asenkron Desen) uygulayan asenkron yöntemini ortaya koyduğundan iyi bir seçim olacaktır.

Kaç kez tek bir eylem yönteminde veritabanını eşzamansız olarak sorgulamak için anahtar kelimeleri bekleyebilirim?

Veritabanı sağlayıcınız tarafından belirtilen kurallara uyduğunuz sürece, istediğiniz kadar. Yapabileceğiniz zaman uyumsuz çağrılar için herhangi bir sınırlama yoktur. Birbirinden bağımsız ve aynı anda yapılabilecek sorgularınız varsa, her biri için yeni bir görev döndürebilir ve her await Task.WhenAllikisinin de tamamlanmasını beklemek için kullanabilirsiniz .


2
Eşzamansız db çağrıları daha hızlı yürütülmez, ancak threadpool iş parçacığı israf edilmediğinden aynı IIS makinesinin çok daha fazla isteği sunucuya sunmasına izin verir. Aynı zamanda CPU maliyetlerini de düşürür, çünkü engelleme çağrıları gerçekte engellemeden önce CPU yoğun bir spinwait ile başlar. Yüksek yük durumlarında bu, makine mücadele eden veya başarısız olan ve geri dönüşüm arasındaki fark olabilir
Panagiotis Kanavos

@PanagiotisKanavos Biliyorum, söylediğimden belirsiz miydi?
Yuval Itzchakov

1
Cevabınız IIS özelliklerinden bahsetmiyor - erime / geri dönüşüm senaryosu, zaman uyumsuzluğu kullanmanın birincil nedenidir. Bunu yaşamamış biri muhtemelen bunun scale out wellanlamını anlamayacaktır your server won't die under load. Veya bu bir durum olabilironce burned ...
Panagiotis Kanavos

7

5 sentim:

  1. async/awaitYalnızca DB veya harici hizmet web hizmeti gibi bir GÇ işlemi gerçekleştiriyorsanız kullanın .
  2. DB'ye her zaman zaman uyumsuz çağrıları tercih edin.
  3. DB'yi her sorguladığınızda.

Not: Nokta 1 için istisnai durumlar vardır, ancak bunun için asenkron içleri iyi anlamanız gerekir.

Ek bir avantaj olarak, gerekirse paralel olarak birkaç IO çağrısı yapabilirsiniz:

Task task1 = FooAsync(); // launch it, but don't wait for result
Task task2 = BarAsync(); // launch bar; now both foo and bar are running
await Task.WhenAll(task1, task2); // this is better in regard to exception handling
// use task1.Result, task2.Result

6

asynceylemler, DB'ye bazı I \ O işlemleri veya isteği işleyen iş parçacığının, yeni çağırdığınız DB veya ağa bağlı çağrıdan yanıt almadan önce durduğu bazı ağa bağlı çağrılar gerçekleştirdiğinde en iyi şekilde yardımcı olur. Onlarla beklemek en iyisidir ve gerçekten uygulamanızın yanıt verebilirliğini artıracaktır (çünkü DB veya bunun gibi herhangi bir işlemi beklerken daha az ASP giriş \ çıkış iş parçacığı durur). Tüm uygulamalarımda, DB'ye çok fazla çağrı yapıldığında, bunları her zaman awaiatable yöntemine sardım ve bunu awaitanahtar kelime ile çağırdım .


5

Bildiğiniz gibi, MVC asenkron kontrolörleri destekler ve bundan faydalanmalısınız. Denetleyicinizin uzun bir işlem gerçekleştirmesi durumunda (disk tabanlı bir G / Ç veya başka bir uzak hizmete ağ çağrısı olabilir), istek eşzamanlı olarak ele alınırsa, IIS iş parçacığı sürekli meşgul olur. Sonuç olarak, iplik sadece uzun işlemin tamamlanmasını bekliyor. İlk olarak talep edilen işlem devam ederken diğer taleplere hizmet edilerek daha iyi kullanılabilir. Bu, daha fazla eşzamanlı istek sunmada yardımcı olacaktır. Web hizmetiniz yüksek oranda ölçeklenebilir olacak ve C10k sorunuyla kolayca karşılaşmayacak . Db sorguları için async / await kullanmak iyi bir fikirdir. ve evet uygun gördüğünüz kadar çok kullanabilirsiniz.

Mükemmel tavsiye için buraya bir göz atın .


3

Deneyimlerim, bugün birçok geliştiricinin async/awaitdenetleyiciler için varsayılan olarak kullanmasıdır .

Benim önerim, sadece size yardımcı olacağını bildiğinizde kullanın .

Nedeni, Stephen Cleary ve diğerlerinin de belirttiği gibi, bunları çözmek yerine performans sorunlarını ortaya çıkarabilir ve sadece belirli bir senaryoda size yardımcı olacaktır:

  • Yüksek trafik kontrolörleri
  • Ölçeklenebilir arka uç

2

ASP.NET MVC'de her yerde zaman uyumsuz eylem kullanmak iyi midir?

Özellikle büyük veri ve hesaplama işlemleri için gerçekleşen çalışan işlem düzeyinde performans sorunlarınız olduğunda, zaman uyumsuz bir yöntemi kullanabileceğiniz her yerde bunu yapmak iyidir. Aksi takdirde, ünite testinin döküme ihtiyacı olacağından gerek yoktur.

Beklenebilir yöntemler ile ilgili: Bir veritabanını sorgulamak istediğimde async / await anahtar sözcüklerini kullanmalı mıyım (EF / NHibernate / other ORM aracılığıyla)?

Evet, çalışan işlemler düzeyinde performans sorunlarından kaçınmak için herhangi bir DB işlemi için zaman uyumsuzluğu kullanmak daha iyidir. EF'in çoğu işlem için aşağıdakiler gibi birçok zaman uyumsuz alternatif oluşturduğunu unutmayın:

.ToListAsync()
.FirstOrDefaultAsync()
.SaveChangesAsync()
.FindAsync()

Tek bir işlem yönteminde veritabanını eşzamansız olarak sorgulamak için anahtar kelimeleri kaç kez kullanabilirim?

Gökyüzü, limittir


Çoğu web uygulaması için iş mantığı genellikle yüksek derecede ardışık işlemlere ihtiyaç duyar, bu nedenle çoğu durumda paralel süreçler arasında atlama, web isteklerinin / alt süreç yönetiminin en üst düzeyinde geçerlidir, bu da doğrudan veritabanı talepleriyle ilgilenmez. Gerçekten DB sorguları zaman uyumsuz bir şekilde işlemek için iyi bir fikir olacağını tipik bir web uygulaması bazı gerçek dünya örnekleri görmek istiyorum.
JustAMartin
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.