
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 handlerdeğilse, aslaasync voidyazmayın. Her zamanTaskdönün ki çağıran taraf hatayı yönetebilsin.
