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 9 | 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. Passarfalse
é 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