Compartilhar via


CA2007: não aguardar diretamente uma tarefa

Property Valor
ID da regra CA2007
Título não aguardar diretamente uma tarefa
Categoria Confiabilidade
Correção interruptiva ou sem interrupção Sem interrupção
Habilitado por padrão no .NET 8 Não

Causa

Um método assíncrono aguarda um Task diretamente.

Descrição da regra

Quando um método assíncrono aguarda um Task diretamente, a continuação normalmente ocorre no mesmo thread que criou a tarefa, dependendo do contexto assíncrono. Esse comportamento pode ser caro em termos de desempenho e pode resultar em um deadlock no thread da IU. Considere chamar Task.ConfigureAwait(Boolean) para sinalizar sua intenção de continuar.

Como corrigir violações

Para corrigir violações, chame ConfigureAwait no Task aguardado. Você pode passar true ou false para o parâmetro continueOnCapturedContext.

  • Chamar ConfigureAwait(true) na tarefa tem o mesmo comportamento que não chamar ConfigureAwaitexplicitamente. Ao chamar explicitamente esse método, você está informando aos leitores que deseja executar intencionalmente a continuação no contexto de sincronização original.

  • Chame ConfigureAwait(false) na tarefa para agendar continuações para o pool de threads, evitando assim um deadlock no thread da interface do usuário. Passar false é uma boa opção para bibliotecas independentes de aplicativo.

Exemplo

O snippet de código abaixo gera o aviso:

public async Task Execute()
{
    Task task = null;
    await task;
}

Para corrigir a violação, chame ConfigureAwait no Task aguardado:

public async Task Execute()
{
    Task task = null;
    await task.ConfigureAwait(false);
}

Quando suprimir avisos

Esse aviso destina-se a bibliotecas, em que o código pode ser executado em ambientes arbitrários e onde ele não deve fazer suposições sobre o ambiente ou como o chamador do método pode estar invocando ou esperando por ele. Geralmente, é apropriado suprimir o aviso inteiramente para projetos que representam o código do aplicativo em vez do código da biblioteca. Na verdade, a execução desse analisador no código do aplicativo (por exemplo, manipuladores de eventos de clique no botão em um projeto WinForms ou WPF) provavelmente fará com que ações erradas sejam tomadas.

Você pode suprimir esse aviso em qualquer situação em que a continuação deve ser agendada novamente para o contexto original ou em situações em que não há esse contexto implementado. Por exemplo, ao escrever código em um manipulador de eventos de clique de botão em um aplicativo WinForms ou WPF, em geral, a continuação de um await deve ser executada no thread da interface do usuário e, portanto, o comportamento padrão de agendar a continuação de volta para o contexto de origem é desejável. Como outro exemplo, ao escrever código em um aplicativo ASP.NET Core, por padrão, não há SynchronizationContext ouTaskScheduler. Por esse motivo, um ConfigureAwait não alteraria nenhum comportamento.

Suprimir um aviso

Para suprimir apenas uma violação, adicione diretivas de pré-processador ao arquivo de origem a fim de desabilitar e, em seguida, reabilitar a regra.

#pragma warning disable CA2007
// The code that's violating the rule is on this line.
#pragma warning restore CA2007

Para desabilitar a regra em um arquivo, uma pasta ou um projeto, defina a severidade como none no arquivo de configuração.

[*.{cs,vb}]
dotnet_diagnostic.CA2007.severity = none

Para obter mais informações, confira Como suprimir avisos de análise de código.

Configurar código para analisar

Use as opções a seguir para configurar em quais partes da base de código essa regra será executada.

Você pode configurar todas essas opções apenas para essa regra, para todas as regras às quais ela se aplica ou para todas as regras nessa categoria (Confiabilidade) às quais ela se aplica. Para mais informações, confira opções de configuração de regra de qualidade de código.

Excluir métodos assíncronos nulos

Você pode configurar se deseja excluir métodos assíncronos que não retornam um valor dessa regra. Para excluir esses tipos de métodos, adicione o seguinte par chave-valor a um arquivo .editorconfig em seu projeto:

# 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

Tipo de saída

Você também pode configurar em quais tipos de assembly de saída aplicar essa regra. Por exemplo, para aplicar essa regra apenas ao código que produz um aplicativo de console ou uma biblioteca vinculada dinamicamente (ou seja, não um aplicativo de interface do usuário), adicione o seguinte par chave-valor a um arquivo .editorconfig em seu projeto:

dotnet_code_quality.CA2007.output_kind = ConsoleApplication, DynamicallyLinkedLibrary

Confira também