Start Debugging

The async and concurrency cheat sheet

Every await decision, and the deadlock it avoids.

This pillar collects everything on the site about asynchronous and concurrent code - the async/await decisions in C#, cancellation, the .NET 11 runtime-async work, the locking and channel primitives, and the deadlocks and exceptions each wrong turn produces.

What to read first

Start with the two calls you make daily: async void vs async Task and .Result vs .Wait() vs GetAwaiter().GetResult() vs await, then the deadlock blocking causes and migrating a legacy codebase to async all the way up. ConfigureAwait(false) vs default in .NET 11 answers whether any of that still matters on modern hosts.

For return types, what ValueTask is and when it’s worth it, IEnumerable vs IAsyncEnumerable vs IQueryable, and returning a Task directly vs an async passthrough cover the signature choices. For running work in parallel, Parallel.ForEach vs Parallel.ForEachAsync vs Task.WhenAll decides, with the AggregateException WhenAll throws as the gotcha. For coordination, lock vs Monitor vs SemaphoreSlim vs System.Threading.Lock and Channels instead of BlockingCollection are the primitives. For shutdown, propagating a CancellationToken and CancelAfter timeouts are the pair.

What’s on this page

The list below auto-collects posts tagged with any of: async, concurrency, threading - which pulls in the Dart and Flutter async posts too. Newest first.

Companion pillars: C# 14 features and the .NET 11 tracker.

Index (38 posts)

2026 / 09

2026 / 08

2026 / 07

2026 / 06

  • How to use BuildContext safely after an await in Flutter

    Capture what you need from the context before the await, then guard the resume with if (context.mounted) return. Here is the full pattern, the lint that enforces it, and the edge cases it misses.

  • What is ValueTask<T> and when is it worth it?

    ValueTask and ValueTask<T> are structs that let an async method return a result without heap-allocating a Task when it completes synchronously. The win is one fewer allocation on hot paths that usually finish without awaiting. The cost is a strict await-once contract. Here is what the type actually is, how it works, and the narrow set of cases where it earns its keep.

  • What is IAsyncEnumerable<T> and when should I use it?

    IAsyncEnumerable<T> is the interface for asynchronous streams: a sequence whose elements arrive over time and each one may require an await. Here is what it actually is, how await foreach and yield drive it, and the rule for when to reach for it over Task<List<T>>.

  • Migrate from ValueTask<T> back to Task<T>: when and why (.NET 11, C# 14)

    A practical checklist for reverting ValueTask and ValueTask<T> return types to Task and Task<T>, what breaks at the call sites, how to verify each change, and how to know whether the swap was ever worth it.

  • Fix: ObjectDisposedException: Cannot access a disposed context instance

    Your fire-and-forget task captured a request-scoped DbContext that the DI scope already disposed. Resolve a fresh context inside the task with IServiceScopeFactory or IDbContextFactory.

2026 / 05

2026 / 04

All pillars Home