Stickied: Required Reading
Pinning Stephen Cleary's blog series on async as required reading for this thread. It is the definitive guide on not blocking on async code in C#.
A collection of async/await anti-patterns that cause deadlocks, thread pool starvation, and mysterious hangs.
Pinning Stephen Cleary's blog series on async as required reading for this thread. It is the definitive guide on not blocking on async code in C#.
Task.Run is for CPU-bound work. Wrapping a synchronous I/O call in Task.Run does not make it truly async — you just burn a thread pool thread while waiting. Use truly async APIs: HttpClient, EF Core async methods, Stream.ReadAsync, and so on.
If you are writing a library (not application code), always use .ConfigureAwait(false) on every await. This avoids capturing the synchronization context and prevents deadlocks in callers who have not gone fully async yet.
async void methods cannot be awaited, so exceptions thrown inside them crash the process. The only valid use case is event handlers. Use async Task everywhere else. I have personally seen this take down a production service.