Partilhar via


CA2012: Usar ValueTasks corretamente

Property valor
ID da regra CA2012
Título Usar ValueTasks corretamente
Categoria Fiabilidade
A correção está quebrando ou não quebrando Sem quebra
Habilitado por padrão no .NET 10 Como sugestão

Motivo

Uma ValueTask instância retornada de uma invocação de membro é usada de uma forma que pode levar a exceções, corrupção ou mau desempenho.

Descrição da regra

ValueTask As instâncias retornadas de invocações de membros devem ser aguardadas diretamente. Tentativas de consumir um ValueTask várias vezes ou acessar diretamente o resultado antes que se saiba que ele foi concluído podem resultar em uma exceção ou corrupção. Ignorar tal ValueTask é provavelmente uma indicação de um bug funcional e pode degradar o desempenho.

Como corrigir violações

Em geral, ValueTasks deve ser aguardado diretamente em vez de descartado ou armazenado em outros locais, como variáveis ou campos locais.

Quando suprimir avisos

Para ValueTask objetos retornados de chamadas de membros arbitrárias, o chamador precisa assumir que o deve ser consumido ValueTask (por exemplo, aguardado) uma vez e apenas uma vez. No entanto, se o desenvolvedor também controla o membro que está sendo invocado e tem conhecimento completo de sua implementação, o desenvolvedor pode saber que é seguro suprimir o aviso, por exemplo, se o retorno ValueTask sempre envolver um Task objeto.

Example

public class NumberValueTask
{
    public async ValueTask<int> GetNumberAsync()
    {
        await Task.Delay(100);
        return 123;
    }

    public async Task UseValueTaskIncorrectlyAsync()
    {
        // This code violates the rule,
        // because ValueTask is awaited multiple times
        ValueTask<int> numberValueTask = GetNumberAsync();

        int first = await numberValueTask;
        int second = await numberValueTask; // <- illegal reuse

        // ...
    }

    // This code satisfies the rule.
    public async Task UseValueTaskCorrectlyAsync()
    {
        int first = await GetNumberAsync();
        int second = await GetNumberAsync();

        // ..
    }

    public async Task UseValueTaskAsTaskAsync()
    {
        ValueTask<int> numberValueTask = GetNumberAsync();

        Task<int> numberTask = numberValueTask.AsTask();

        int first = await numberTask;
        int second = await numberTask;

        // ...
    }
}

Suprimir um aviso

Se você quiser apenas suprimir uma única violação, adicione diretivas de pré-processador ao seu arquivo de origem para desativar e, em seguida, reativar a regra.

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

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

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

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

Consulte também