CA2007: Do not directly await a Task
Property | Value |
---|---|
Rule ID | CA2007 |
Title | Do not directly await a Task |
Category | Reliability |
Fix is breaking or non-breaking | Non-breaking |
Enabled by default in .NET 8 | No |
Cause
An asynchronous method awaits a Task directly.
Rule description
When an asynchronous method awaits a Task directly, continuation usually occurs in the same thread that created the task, depending on the async context. This behavior can be costly in terms of performance and can result in a deadlock on the UI thread. Consider calling Task.ConfigureAwait(Boolean) to signal your intention for continuation.
How to fix violations
To fix violations, call ConfigureAwait on the awaited 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 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. Passingfalse
is a good option for app-independent libraries.
Example
The following code snippet generates the warning:
public async Task Execute()
{
Task task = null;
await task;
}
To fix the violation, call ConfigureAwait on the awaited Task:
public async Task Execute()
{
Task task = null;
await task.ConfigureAwait(false);
}
When to suppress warnings
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 SynchronizationContext or TaskScheduler, for which reason a ConfigureAwait
wouldn't actually change any behavior.
Suppress a warning
If you just want to suppress a single violation, add preprocessor directives to your source file to disable and then re-enable the rule.
#pragma warning disable CA2007
// The code that's violating the rule is on this line.
#pragma warning restore CA2007
To disable the rule for a file, folder, or project, set its severity to none
in the configuration file.
[*.{cs,vb}]
dotnet_diagnostic.CA2007.severity = none
For more information, see How to suppress code analysis warnings.
Configure code to analyze
Use the following options to configure which parts of your codebase to run this rule on.
You can configure all of these options for just this rule, for all rules it applies to, or for all rules in this category (Reliability) that it applies to. For more information, see Code quality rule configuration options.
Exclude async void methods
You can configure whether you want to exclude asynchronous methods that don't return a value from this rule. To exclude these kinds of methods, add the following key-value pair to an .editorconfig file in your project:
# Package version 2.9.0 and later
dotnet_code_quality.CA2007.exclude_async_void_methods = true
# Package version 2.6.3 and earlier
dotnet_code_quality.CA2007.skip_async_void_methods = true
Output kind
You can also configure which output assembly kinds to apply this rule to. For example, to only apply this rule to code that produces a console application or a dynamically linked library (that is, not a UI app), add the following key-value pair to an .editorconfig file in your project:
dotnet_code_quality.CA2007.output_kind = ConsoleApplication, DynamicallyLinkedLibrary