Async / Await, Task & ThreadPool Starvation
Uzun süren veritabanı veya HTTP isteklerinde işlemci çekirdeğini (thread) kilitlemeden serbest bırakmaktır.
Restoranda garsonun yemeğin fırında pişmesini beklerken fırının önünde dikilmeyip diğer masaların siparişini almasıdır. Fırından zil sesi gelince gidip yemeği masaya götürür.
I/O operasyonlarında thread-blocking yapmadan CPU kaynaklarını serbest bırakan modeldir. Arka planda derleyici bir State Machine (Durum Makinesi) üretir. Task bir iş emrini, Thread ise o işi koşturan fiziksel OS kaynağını temsil eder. .Result veya .Wait() ile senkrona çevrilirse ThreadPool tükenir (Thread Starvation).
“Async/Await yeni bir thread açmak demek değildir; I/O bekleme süresinde thread'i serbest bırakarak ThreadPool'un tükenmesini (thread starvation) önlemektir. Asenkron metotların sonucunu .Result veya .Wait() ile senkrona çevirmek sync-over-async kilitlenmeye (Deadlock) sebep olur.”
public async Task<UserDto> GetUserAsync(int id)
{
using var client = new HttpClient();
var json = await client.GetStringAsync("https://api.site.com/user/" + id);
return JsonSerializer.Deserialize<UserDto>(json);
}
Asenkron metodu Task.Result veya .Wait() ile çağırmak ASP.NET SynchronizationContext ortamında Deadlock garantisidir.