Async Void vs Async Task

Async Void vs Async Task

Selamlar,

Bu yazıda C# da asenkron programlama yaparken kullanabileceğimiz geri dönüş tiplerinden void ve Task ı inceleyeceğiz.

C# dilinde, asenkron programlama yapmak için async ve await anahtar kelimeleri kullanılır. Async anahtar kelimesi, bir metodun asenkron olarak çalıştırabileceğini belirtir. Await anahtar kelimesi ise, bir asenkron işlemin tamamlanmasını bekler ve işlem tamamlandığında kodun devam etmesini sağlar. Asenkron programlama, performansı artırmak, kullanıcı arayüzünü dondurmadan arka planda işlem yapmak, birden fazla işlemi eş zamanlı olarak çalıştırmak gibi pek çok avantaj sağlar.

Asenkron bir metodun dönüş tipi, async anahtar kelimesi ile belirtilir. Asenkron bir metodun dönüş tipi, void, Task veya Task<T> olabilir. Bu dönüş tipleri arasındaki farklar, asenkron metodun nasıl çağrıldığı, nasıl bekletildiği, nasıl hata yönetimi yapıldığı gibi konularda önemli rol oynar. Bu yazıda, asenkron metodların dönüş tipleri olan async void ve async Task arasındaki farkları, çalışma biçimlerini inceleyeceğiz.

Async Void

Async void, asenkron bir metodun dönüş tipi olarak kullanıldığında, metodun geriye bir değer döndürmediğini veya bir Task nesnesi oluşturmadığını belirtir. Bu tip asenkron metodlar fire and forget olarak adlandırılır. Bu metodlar, çağrıldıklarında arka planda çalışmaya başlarlar ve tamamlandıklarında herhangi bir bildirim yapmazlar. Bu metodları çağıran kod, bu metodların ne zaman tamamlandığını veya tamamlanıp tamamlanmadığını bilemez. Bu metodları await ile bekletmek de mümkün değildir. Bu metodlar, sadece void dönüş tipine sahip olması gereken durumlarda, örneğin event handler işlemlerinde kullanılmalıdır.

Async void metodların avantajı, event handler da asenkron programlama yapmaya imkan vermesidir. Örneğin, bir butona tıklandığında, arka planda uzun süren bir işlem yapmak istiyorsak, bu işlemi async void bir metod içinde yapabiliriz. Böylece, kullanıcı arayüzü donmadan, işlemi asenkron olarak çalıştırabiliriz. Async void metodların dezavantajı ise, hata yönetimi, performans takibi, işlem durumu gibi konularda zorluk çıkarmasıdır. Örneğin, bir async void metod içinde bir hata oluşursa, bu hata metodun çağrıldığı yere iletilemez. Bu hata, sadece uygulama seviyesinde yakalanabilir. Ayrıca, bir async void metodun ne kadar sürede tamamlandığını veya tamamlanıp tamamlanmadığını ölçmek de mümkün değildir. Bu da performans analizi yapmayı zorlaştırır. Aşağıda bu kullanım için örnek kod verilmiştir.

public async void DoSomethingAsync()
{
     await Task.Delay(3000);
     throw new Exception("Something went wrong");
}
public void CallAsyncMethod()
{
     DoSomethingAsync();
     Console.WriteLine("Hello");
}

Burada CallAsyncMethod içinde geriye void döndüren DoSomethingAsync metodu çağrılmıştır. DoSomethingAsync içerisinde await ile 3 saniye beklenmiş ardından bir exception fırlatılmıştır. Ancak burada geriye void dönderildiği için bu exception yakalanamayacaktır.

Şimdi de async Task konusunu inceleyelim ve bu kullanımda neden exception vs. bilgileri yakalayabiliyoruz onları gözlemleyelim.

Async Task

Async Task, geri dönüş tipi Task olan bir asenkron metottur. Bu tip metotlar, await edilebilir, yani çağıran metot, asenkron metot tamamlanana kadar bekler. Bu metotlar, asenkron olarak çalışır, ancak tamamlandıklarında ne olduğunu bilebiliriz.

Async Task metotlarının avantajı, hata yönetimi, performans takibi ve iş akışı kontrolü gibi konularda kolaylık sağlamasıdır. Örneğin, bir async Task metodu içinde bir hata oluşursa, bu hata, çağıran metoda ulaşır ve try-catch blokları ile yakalanabilir. Ayrıca, bir async Task metodu tamamlandığında, bunu await anahtar kelimesi ile bilebilir ve bununla ilgili bir işlem yapabiliriz. Bu da, performansı ölçmek veya iş akışını yönetmek için imkan verir. Şimdi de bir async Task ile örnek yapalım.

public async Task<int> GetNumberAsync()
{
    await Task.Delay(3000);
    throw new Exception("Something went wrong");
}

public async Task CallAsyncMethod()
{
    try
    {
        int number = await GetNumberAsync();
        Console.WriteLine(number);
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}

Burada CallAsyncMethod metodu içerisinde GetNumberAsync metodunu çağırıyoruz. GetNumberAsync metodu 3 saniye bekleyip exception fırlatan ve geri dönüş tipi bir Task<int> olan async metotdur. CallAsyncMethod içerisinde await GetNumberAsync() çağırımı sonrası GetNumberAsync içerisinde hata fırlatılacaktır. Asycn void den farklı olarak burada geriye Task döndüğümüz için bu hata çağıran metoda iletilecek ve CallAsyncMethod içerisinde ilgili hata catch bloğunda yakalanabilecektir. Peki void yerine Task dönmek başta hata yakalama olmak üzere diğer konularda nasıl yardımcı oluyor?

Async Task metotlarının hata yakalama özelliği, Task tipinin bir hata durumunu temsil edebilmesinden kaynaklanır. Task tipi, asenkron bir işlemin sonucunu veya durumunu tutan bir nesnedir. Bir Task nesnesi, başarılı, başarısız veya iptal edilmiş olabilir. Bir Task nesnesi başarısız olduğunda, içinde bir AggregateException nesnesi barındırır. Bu nesne, asenkron işlem sırasında oluşan tüm hataları içerir. Bu nesneye, Task nesnesinin Exception özelliği ile erişilebilir. Bu sayede, asenkron işlemde oluşan hataları yakalamak ve işlemek mümkün olur.

Async void metotlarının hata yakalama özelliği yoktur, çünkü void tipi bir hata durumunu temsil edemez. Void tipi, bir değer veya sonuç döndürmeyen bir işlemi ifade eder. Bir async void metodu içinde bir hata oluştuğunda, bu hata, çağıran metoda ulaşmaz. Böylece hata yakalanamamış olur.

Bu yazıda async void ve Async Task kullanımlarını temel anlamda incelemiş olduk.

Sonuç olarak, async Task genellikle daha esnek, hataya dayanıklı ve yönetilebilir bir seçenek sunar. Ancak, event handler gibi belirli durumlarda da async void uygun olabilir. Uygulamalarımızın gereksinimlerine ve yaptığı işe göre doğru olanı tercih etmek uygulamanın dayanıklılığı konusunda büyük önem arz etmektedir.

İyi çalışmalar.

Yorum bırakın