Asenkron içinde Senkron Kod Kullanımı ve Thread Exhaustion Problemi

Gökberk Timurözü
Kariyer.net Tech
2 min readJun 26, 2024

--

Asenkron programlama, özellikle I/O işlemlerinde uygulamaların daha verimli çalışmasını sağlar.

Ancak asenkron kod içinde senkron metotlar kullanmak yüksek trafik alan uygulamalarda ciddi performans sorunları yaratabilir. Bu makalede, bu yanlış kullanımdan doğabilecek Thread Exhaustion (iş parçacığı tükenmesi) sorununa değineceğiz.

Thread Exhaustion Nedir ?

Thread Exhaustion, thread pool’da ki tüm threadlerin tükendiği durumu ifade eder.

Bu, uygulamamız için yeni thread oluşmaması ve mevcut threadlerin bloklanması sonucunda meydana gelir. Asenkron işlemler sırasında, asenkron metotların yanlış kullanımı nedeniyle ortaya çıkabilir.

Örnek olarak, asenkron bir metodu senkron olarak çağırmak;

public async Task DoSomethingAsync()
{
await Task.Delay(1000);
}

public async Task<string> ReturnSomethingAsync()
{
await Task.Delay(1000);
return string.Empty;
}

public void CallAsyncMethodSynchronously()
{
//Asenkron metodu senkron çağırma örneği 1
DoSomethingAsync().Wait();

//Asenkron metodu senkron çağırma örneği 2
var result = ReturnSomethingAsync().Result;
}

Thread Exhaustion’ın Gerçek Hayattan Bir Örneği

Parametre olarak aldığı “url” değişkenine göre başka bir api’a istek atıp sonuç bekleyen bir web uygulaması düşünelim.

public async Task<string> GetDataFromApiAsync(string url)
{
using (HttpClient client = new HttpClient())
{
HttpResponseMessage response = await client.GetAsync(url);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
}

public string GetDataSynchronously(string url)
{
return GetDataFromApiAsync(url).Result;
}

GetDataSynchronously metodu kullanıcıdan gelen her isteği senkronize olarak işler. Yoğun yük altında thread pool’da ki tüm threadlerin bloklandığı noktada “thread exhaustion” yaşanacak, yeni gelen istekler işlenemeyecek ve uygulamamız yanıt veremez hale gelecektir. Bu durumdan kaçınmak için asenkron kodun doğru kullanımı aşağıdaki gibi olmalıdır;

public async Task<string> GetDataAsynchronously(string url)
{
return await GetDataFromApiAsync(url);
}

Sonuç

Asenkron programlama, doğru kullanıldığı zaman uygulama performansına olumlu etkide bulunabilir. Ancak, asenkron işlemler içinde senkron metot kullanımları yukarıdaki örneklerdeki gibi thread exhaustion’a yol açabilir. Asenkron kodların tam anlamıyla asenkron yazılması, “.Result” ve “.Wait()” gibi çağrımlardan gerekmedikçe kaçınmak bu tür sorunları önlemek için doğru bir yaklaşım olacaktır.

Konu hakkında daha fazla okuma yapmak için bazı anahtar kelimeler;

Thread : İş Parçacığı

ThreadPool : İş Parçacığı Havuzu

Thread Exhaustion : İş parçacığı sınırına ulaşmak

ThreadPool Starvation : Gelen istekleri işlemek için yeterli iş parçacığının olmaması durumu

Kaynakça;

https://learn.microsoft.com/en-us/dotnet/core/diagnostics/debug-threadpool-starvation

--

--