Use when writing, reviewing, or refactoring C# async code, especially for Task and ValueTask usage, cancellation, ConfigureAwait, async streams, sync-over-async issues, and Channel-based concurrency.
Use this skill when writing, reviewing, or refactoring asynchronous C# code, including task management, cancellation, streaming, and concurrency patterns.
ValueTask and eliding.Async.Task for void-returning async methods and Task<T> for value-returning ones.ValueTask or ValueTask<T> only when measured beneficial — typically for hot paths that complete synchronously most of the time.async voidCancellationToken as the last parameter in any method that performs cancelable work.CancellationToken through the entire call chain.cancellationToken.ThrowIfCancellationRequested() in loops or before expensive operations.await Task.Delay(ms, cancellationToken).CancellationTokenSource with CancelAfter rather than Task.WhenAny with a timer task.OperationCanceledException propagate; do not swallow it.ConfigureAwait(false) in reusable library code and helper methods that do not need the original synchronization context.ConfigureAwait in ASP.NET Core application code, which has no synchronization context by default.ConfigureAwait in UI application code (WPF, WinForms, MAUI) when the continuation needs the UI thread..Wait(), .Result, or .GetAwaiter().GetResult() on a task in code that could run on a thread-pool or UI thread.Task.Run as a last resort in desktop apps, and document why.await.Task.FromException<T>() or ValueTask.FromException<T>() when returning a faulted task from a non-async method.async Task methods are captured in the returned task, while async void exceptions crash the process.Task.WhenAll() to await multiple independent tasks concurrently.Parallel.ForEachAsync() (.NET 6+) for data-parallel async work with a configurable degree of concurrency.Task.WhenAny() when racing tasks; always observe or cancel the losing tasks.IAsyncEnumerable<T> and await foreach for sequences produced asynchronously.[EnumeratorCancellation] CancellationToken to async iterator methods.WithCancellation(token) at the consumption site.Channel<T> for producer-consumer patterns instead of BlockingCollection<T> in async code.BoundedChannelFullMode) for load control.IAsyncDisposable and dispose resources with await using when the cleanup involves I/O.DisposeAsync, cancel ongoing work, flush buffers, and release async resources.IDisposable and IAsyncDisposable, prefer await using in async code paths.using / try-finally, consider returning the task directly without async / await to avoid the state-machine overhead.async / await when the method has a using statement, a try block, or disposes resources — the state machine is needed to keep the scope alive.ValueTask<T> over Task<T> only in hot paths where the result is cached or synchronously available most of the time.ValueTask more than once.Task.CompletedTask or ValueTask.CompletedTask to avoid allocations for synchronous completions.StringBuilder or pooling for I/O buffers in async loops rather than allocating per iteration..Result, .Wait(), .GetAwaiter().GetResult()).CancellationToken is accepted and propagated where cancelable work exists.Task or ValueTask, never async void (except event handlers).await using or using appropriately.Task.WhenAll or bounded parallelism, not unbounded Task.Run loops.ConfigureAwait(false) is used correctly in library code.