值
规则 ID
CA2007
类别
可靠性
修复是中断修复还是非中断修复
非中断
原因
异步方法会直接等待 Task。
规则说明
异步方法直接等待 Task 时,延续任务通常会出现在创建任务的同一线程中,具体取决于异步上下文。 此行为可能会降低性能,并且可能会导致 UI 线程发生死锁。 请考虑调用 Task.ConfigureAwait(Boolean) 以表示延续任务意图。
如何解决冲突
若要解决冲突,请在等待的 Task 上调用 ConfigureAwait。 可以为 continueOnCapturedContext 参数传递 true 或 false。
对任务调用 ConfigureAwait(true) 与未显式调用 ConfigureAwait 的行为相同。 通过显式调用此方法,可让读取者知道你是有意要对原始同步上下文执行延续任务。
对任务调用 ConfigureAwait(false) 可将延续任务安排到线程池,从而避免 UI 线程上出现死锁。 对于与应用无关的库,传递 false 是一个好的选择。
示例
下面的代码片段会生成此警告:
public async Task Execute()
{
Task task = null;
await task;
}
若要解决此冲突,请在等待的 Task 上调用 ConfigureAwait:
public async Task Execute()
{
Task task = null;
await task.ConfigureAwait(false);
}
何时禁止显示警告
此警告适用于库,在库中,可能会在任意环境中执行代码,而代码不应对环境或方法的调用方如何调用或等待作出假设。 一般来说,对于代表应用程序代码(而不是库代码)的项目,可完全禁止显示此警告;事实上,在应用程序代码上运行该分析器(例如 WinForms 或 WPF 项目中的按钮单击事件处理程序)很可能会导致执行错误的操作。
如果应将延续任务安排回原始上下文,或者还没有此类上下文,都可禁止显示此警告。 例如,在 WinForms 或 WPF 应用程序中的按钮单击事件处理程序中编写代码时,通常情况下,等待的延续任务应在 UI 线程上运行,因而需要将延续任务安排回原始上下文的默认行为。 另举一例,在 ASP.NET Core 应用程序中编写代码时,默认情况下没有 SynchronizationContext 或 TaskScheduler,原因是 ConfigureAwait 不会实际更改任何行为。
抑制警告
可以通过多种方式来禁止显示代码分析警告,包括禁用项目的规则、使用预处理器指令为特定代码行禁用该规则或应用 SuppressMessageAttribute 特性。 有关详细信息,请参阅如何禁止显示代码分析警告。
配置代码以进行分析
使用下面的选项来配置代码库的哪些部分要运行此规则。
排除 async void 方法
输出类型
可以仅为此规则、为所有规则或为此类别(可靠性)中的所有规则配置所有这些选项。 有关详细信息,请参阅代码质量规则配置选项。
排除 async void 方法
可配置是否要排除不从此规则返回值的异步方法。 要排除这些类型的方法,需将以下键值对添加到项目中的 .editorconfig 文件:
# 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
输出类型
还可以配置此规则要应用的输出程序集种类。 例如,如果仅将此规则应用于生成控制台应用程序或动态链接库的代码(即不是 UI 应用),需将以下键值对添加到项目中的 .editorconfig 文件:
dotnet_code_quality.CA2007.output_kind = ConsoleApplication, DynamicallyLinkedLibrary
另请参阅
ConfigureAwait 常见问题解答
是否应使用 ConfigureAwait (false) 来等待任务?
CA2008:不要在未传递 TaskScheduler 的情况下创建任务
可靠性规则
本文系外文翻译,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文系外文翻译,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。