⚡ Async All the Way Up
Async/await is powerful but dangerous. Deadlocks, thread pool starvation, sync-over-async — avoid common pitfalls with these patterns.
❌ Deadlock Pattern
// UI or ASP.NET Context - DEADLOCK!
public void Button_Click(object sender, EventArgs e)
{
var result = GetDataAsync().Result; // 💀 DEADLOCK
}
public async Task GetDataAsync()
{
await Task.Delay(1000);
return "data";
}
✅ Fix: Async All the Way
public async void Button_Click(object sender, EventArgs e)
{
var result = await GetDataAsync(); // ✅ No deadlock
}
// Or use ConfigureAwait(false)
public async Task GetDataAsync()
{
await Task.Delay(1000).ConfigureAwait(false);
return "data";
}
📝 Best Practices
// 1. Name async methods with Async suffix public async TaskFetchDataAsync() { } // 2. Avoid async void (except event handlers) public async void Button_Click() { } // OK public async Task DoWorkAsync() { } // Preferred // 3. ConfigureAwait(false) for library code await db.SaveChangesAsync().ConfigureAwait(false); // 4. Don't block on async code var result = await GetDataAsync(); // ✅ Good var result = GetDataAsync().Result; // ❌ Bad var result = GetDataAsync().GetAwaiter().GetResult(); // ❌ Bad // 5. Use ValueTask for high-performance scenarios public async ValueTask GetCachedValueAsync() { } // 6. WhenAll for parallel operations var task1 = GetUserAsync(); var task2 = GetOrdersAsync(); await Task.WhenAll(task1, task2);
✅ Common Anti-Patterns to Avoid
- Async void: Only for event handlers (exceptions crash app)
- .Result or .Wait(): Causes deadlocks in sync contexts
- async without await: Compiler warning, runs synchronously
- Blocking in async method: Thread.Sleep (use await Task.Delay)
- Creating async lambda without awaiting
💡 When to Use ConfigureAwait(false)
- Library code: Always use (no synchronization context needed)
- Application code (UI): Don’t use (need context for UI updates)
- ASP.NET Core: No synchronization context, so no difference
- Console apps: Doesn’t matter (no synchronization context)
“WPF app froze completely on button click. Used .Result in event handler. Fixed with async/await all the way. App responsive again. Learn async best practices before you need them.”
