async/await tuzakları
Deadlock ve sync-over-async gibi yaygın tuzakları öğrenirsin.
Kilitlenme tuzağı
Senkron kodun içinden bir async metodu .Result ya da .Wait() ile beklemek kilitlenmeye (deadlock) yol açabilir. ASP.NET veya WinForms gibi tek iş parçacıklı bağlamlarda, async metodun devamı senkron bekleyen parçacığı bekler; ikisi birbirini bekler.
Önlemi: .Result yerine await kullan. Bağlam yakalamayı önlemek için ConfigureAwait(false) de işe yarar. İlke: senkron kodun içinden async metot çağırma.
ConfigureAwait(false)
ConfigureAwait(false), await sonrası bağlam yakalamayı önler. Bu, kütüphane kodunda önerilir: çağıranın bağlamına dönmek zorunda değilsin, devam herhangi bir parçacıkta çalışır. Bu kilitlenme riskini azaltır.
Kullanım: await DoAsync().ConfigureAwait(false);. UI kodunda ise varsayılan davranışı korumak için ConfigureAwait(true) (varsayılan) kullanılır; çünkü UI güncellemeleri UI parçacığında yapılmalıdır.
Uygulama Kilitlenmeyi await ile düzelt
static async Task<string> Fetch() metodunu tanımla. Gövdede await Task.CompletedTask ve return "Veri"; yaz. Main'i static async Task Main yap. string data = await Fetch(); ile sonucu al ve Console.WriteLine(data); ile yazdır.
Örnek çözümü göster
Fetch gövdesinde await Task.CompletedTask ve return "Veri" yaz. Main'i static async Task Main() yapıp string data = await Fetch(); Console.WriteLine(data);
Örnek çözüm:
using System;
using System.Threading.Tasks;
class Program
{
static async Task<string> Fetch()
{
await Task.CompletedTask;
return "Veri";
}
static async Task Main()
{
string data = await Fetch();
Console.WriteLine(data);
}
}
Kendini test et
-
.Result yerine await kullan
string data = ____ FetchAsync();Cevabı göster
string data = await FetchAsync(); -
Hangisi kilitlenmeye yol açabilir?
- await Task.Delay(100)
- await Task.Run(() => Work())
- string s = await FetchAsync();
- Task.Run(() => Work()).GetAwaiter().GetResult()
Cevabı göster
Task.Run(() => Work()).GetAwaiter().GetResult() — Doğru. Senkron bekleyen kod içinden async çağrı kilitlenmeye yol açar.
-
Kavramları eşleştir
- .Result
- Kilitlenmeye yol açabilir
- await
- Güvenli bekleme
- ConfigureAwait(false)
- Bağlam yakalamaz
- async void
- Yalnızca olay işleyici