Performans ve önbellek
async/await, thread pool ve ölçeklenme
Async kodu hızlandırmaz; beklerken iş parçacığını serbest bırakarak daha çok isteğe hizmet etmeyi sağlar.
Kavramı anlayalım
ASP.NET Core istekleri thread pool’daki iş parçacıklarıyla işler. Bir istek veritabanını veya başka bir servisi beklerken senkron kod iş parçacığını boşuna meşgul eder. await ise bekleme süresince iş parçacığını havuza geri verir; işlem bitince devam başka bir iş parçacığında sürebilir. Böylece aynı sayıda iş parçacığıyla çok daha fazla eşzamanlı istek karşılanır.
Bu yüzden G/Ç yapan her çağrı async olmalıdır: ToListAsync, SaveChangesAsync, HttpClient.GetAsync, ReadAsync. Async metotlar zincir boyunca async kalmalıdır. Async bir metodu .Result veya .Wait() ile senkron beklemek (sync-over-async) iş parçacığını kilitler; yük altında thread pool tükenir ve uygulama CPU boşta olduğu halde yanıt vermez hale gelir.
CancellationToken, istemci bağlantıyı kapattığında veya zaman aşımı olduğunda işi durdurmayı sağlar. ASP.NET Core her istek için bir token verir (HttpContext.RequestAborted veya action parametresi). Bunu EF Core ve HttpClient çağrılarına geçirmek, kimsenin beklemediği sorguların boşuna çalışmasını önler.
Thread pool açlığı, yük altında uygulamanın aniden donmasının en yaygın nedenlerinden biridir.
Async bir çağrıyı .Result ile beklemek veya async void kullanmak.
Aynı konu. Üç farklı derinlik.
// ✗ Senkron: bekleme süresince iş parçacığı meşgul
var posts = db.Posts.ToList();
// ✓ Async: bekleme süresince iş parçacığı serbest
var posts = await db.Posts.ToListAsync(ct);Sonuç aynıdır; fark, beklerken iş parçacığının ne yaptığıdır.
Bu sayfa gerçek bir sunucuya veya veritabanına bağlanmaz. Kod örnekleri .NET 8, Next.js ve SQL Server için temsilîdir; süreler simülasyondaki örnek değerlerdir, ölçüm değildir. Örnekleri yalnız kendi geliştirme ortamında dene; gerçek bağlantı dizesi, token veya parola paylaşma.
Önce kendin dene.
Yük testinde 200 eşzamanlı kullanıcıda yanıt süreleri 30 saniyeye çıkıyor, CPU %15, veritabanı rahat. Kodda ne ararsın?
Çözümü ve açıklamasını göster
.Result / .Wait() / GetAwaiter().GetResult() kullanımları,
senkron G/Ç (File.ReadAllText, ToList, SaveChanges),
Thread.Sleep. Hepsi iş parçacığını kilitler → thread pool açlığı.Kaynaklar boştayken sistemin beklemesi, iş parçacıklarının bloke olduğuna işaret eder.