Asenkron Programlama ve Task Yönetimi¶
Asenkron programlama, modern uygulamalarda performans ve yanıt verebilirlik açısından büyük önem taşır. Ancak, yanlış kullanıldığında beklenmedik sorunlara yol açabilir. İşte C#’ta asenkron programlama için sık yapılan hatalar ve önerilen çözümler.
1. await Kullanımını Atlamak¶
❌ Yanlış Kullanım: await kullanılmadığında istisna durumları doğru şekilde ele alınamaz.
try
{
DoWorkWithoutAwaitAsync();
}
catch (Exception e)
{
Console.WriteLine($"Hata: {e.Message}");
}
static Task DoWorkWithoutAwaitAsync()
{
return ThrowExceptionAsync();
}
static async Task ThrowExceptionAsync()
{
await Task.Yield();
throw new Exception("Bir hata oluştu!");
}
✅ İdeal Kullanım: await ile çağrıyı bekleyerek hata yönetimini iyileştirin.
try
{
await DoWorkWithAwaitAsync();
}
catch (Exception e)
{
Console.WriteLine($"Hata: {e.Message}");
}
static async Task DoWorkWithAwaitAsync()
{
await ThrowExceptionAsync();
}
static async Task ThrowExceptionAsync()
{
await Task.Yield();
throw new Exception("Bir hata oluştu!");
}
2. async void Kullanımı¶
❌ Yanlış Kullanım: async void hataları doğru bir şekilde ele almayı zorlaştırır.
public async void DoAsync()
{
await SomeAsyncOperation();
}
✅ İdeal Kullanım: async Task kullanarak hata yönetimini ve test edilebilirliği artırın.
public async Task DoAsync()
{
await SomeAsyncOperation();
}
💡 Not:
async voidyalnızca olay işleyicileri gibi özel durumlarda kullanılmalıdır.
3. Task Nesnesini Beklemeden Döndürmek¶
❌ Yanlış Kullanım: using bloğu içinde Task nesnesini beklemeden döndürmek kaynakların erken serbest bırakılmasına neden olabilir.
public Task<string> GetContentAsync()
{
using var client = new HttpClient();
return client.GetStringAsync("https://example.com");
}
✅ İdeal Kullanım: await kullanarak kaynak yönetimini doğru yapın.
public async Task<string> GetContentAsync()
{
using var client = new HttpClient();
return await client.GetStringAsync("https://example.com");
}
4. Paralel İşlemlerin Yanlış Yönetimi¶
❌ Yanlış Kullanım: Paralel görevleri sırayla beklemek.
await Task1();
await Task2();
✅ İdeal Kullanım: Görevleri paralel olarak başlatıp aynı anda beklemek.
var task1 = Task1();
var task2 = Task2();
await Task.WhenAll(task1, task2);
5. Task.Delay ile Hassas Bekleme¶
❌ Yanlış Kullanım: Kısa süreli hassas bekleme için Task.Delay kullanmak.
await Task.Delay(1); // Süre tam olarak 1ms olmayabilir.
✅ İdeal Kullanım: Hassas zamanlama için daha uygun araçlar kullanın.
6. Deadlock Sorunları¶
❌ Yanlış Kullanım: Task.Result veya Task.Wait kullanarak deadlock oluşturmak.
var result = SomeAsyncOperation().Result;
✅ İdeal Kullanım: await kullanarak deadlock sorunlarını önleyin.
var result = await SomeAsyncOperation();
7. Task Nesnelerini Geri Dönüştürmek¶
❌ Yanlış Kullanım: Her işlem için yeni bir Task nesnesi oluşturmak.
public Task<int> GetNumberAsync()
{
return Task.Run(() => 42);
}
✅ İdeal Kullanım: Task.FromResult kullanarak gereksiz nesne oluşturmayı önleyin.
public Task<int> GetNumberAsync()
{
return Task.FromResult(42);
}