All rules
CA2007Reliability Enabled by default: No MS default: Warning

Do not directly await a Task

Call `ConfigureAwait(false)` on awaited tasks in library code.

Microsoft docs

Description

Recommends specifying ConfigureAwait when awaiting a Task to make context-capturing behavior explicit, especially important in library code.

Cause

An asynchronous method awaits a System.Threading.Tasks.Task directly.

Why it matters

Capturing the synchronization context unnecessarily can cause deadlocks and performance issues in libraries.

How to fix violations

To fix violations, call System.Threading.Tasks.Task.ConfigureAwait on the awaited System.Threading.Tasks.Task. You can pass either true or false for the continueOnCapturedContext parameter.

  • Calling ConfigureAwait(true) on the task has the same behavior as not explicitly calling System.Threading.Tasks.Task.ConfigureAwait. By explicitly calling this method, you're letting readers know you intentionally want to perform the continuation on the original synchronization context.
  • Call ConfigureAwait(false) on the task to schedule continuations to the thread pool, thereby avoiding a deadlock on the UI thread. Passing false is a good option for app-independent libraries.

Examples

Avoid
await DownloadAsync();
Prefer
await DownloadAsync().ConfigureAwait(false);

When to suppress

This warning is intended for libraries, where the code may be executed in arbitrary environments and where code shouldn't make assumptions about the environment or how the caller of the method may be invoking or waiting on it. It is generally appropriate to suppress the warning entirely for projects that represent application code rather than library code; in fact, running this analyzer on application code (for example, button click event handlers in a WinForms or WPF project) is likely to lead to the wrong actions being taken.

You can suppress this warning in any situation where either the continuation should be scheduled back to the original context or where there is no such context in place. For example, when writing code in a button click event handler in a WinForms or WPF application, in general the continuation from an await should run on the UI thread, and thus the default behavior of scheduling the continuation back to the originating context is desirable. As another example, when writing code in an ASP.NET Core application, by default there is no System.Threading.SynchronizationContext or System.Threading.Tasks.TaskScheduler, for which reason a ConfigureAwait wouldn't actually change any behavior.

Group results
0 yes 0 no
ConsensusNone (disabled)
Severity preference (yes voters)
Suggestion0
Warning0
Error0