Menü

Neominal

BT Hizmetleri ve Danışmanlığı

29 Nisan 20262 dk okuma14 görüntüleme
Part 7: C# Async/Parallel Hata Yönetimi

Senkron kodda hata yönetimi kolaydır; hata fırlatılır ve stack trace üzerinden takip edilir. Ancak asenkron ve paralel dünyada, hata fırlatan thread çoktan "ölmüş" veya "havuza dönmüş" olabilir. İyi bir geliştirici, asenkron hataların yutulmasına (swallowing) asla izin vermez.

1. Task Hataları

Bir Task içinde hata oluştuğunda, bu hata hemen fırlatılmaz. Task nesnesinin içine paketlenir. Eğer siz o Task'ı await etmezseniz, hata "yutulur" ve uygulamanız garip davranmaya başlar.

// TEHLİKELİ: Hata asla yakalanamaz!
public void FireAndForget()
{
    Task.Run(() => throw new Exception("Boom!")); 
}

// DOĞRU: Hata await edildiği an fırlatılır.
public async Task HandleIt()
{
    try {
        await Task.Run(() => throw new Exception("Boom!"));
    }
    catch(Exception ex) {
        Console.WriteLine(ex.Message);
    }
}

2. Parallel.ForEach ve AggregateException

Paralel bir döngüde birden fazla işlem hata verdiğinde, .NET bunları tek bir pakete koyar: AggregateException. Bu, içinde birden fazla hatayı barındıran özel bir zarftır.

try
{
    Parallel.ForEach(data, item => {
        if(item == null) throw new ArgumentNullException();
    });
}
catch (AggregateException ae)
{
    // Tüm hataları tek tek gezebiliriz
    foreach (var ex in ae.InnerExceptions)
    {
        Console.WriteLine($"Hata: {ex.GetType().Name}");
    }
    
    // Veya sadece belirli hataları "handle" edip gerisini fırlatabiliriz
    ae.Handle(x => x is ArgumentNullException); 
}

3. Async Void

async void metodlarda hata yakalayacak bir Task nesnesi olmadığı için, bu metodun içinde fırlayan bir hata doğrudan AppDomain'e gider ve tüm uygulamayı (Crash) çökertir.

Tavsiye: Bir metod event handler değilse, asla async void yazmayın. Her zaman Task dönün ki çağıran taraf hatayı yönetebilsin.