Comparteix a través de


CA2012: Usar ValueTasks correctamente

Propiedad Valor
Identificador de la regla CA2012
Título Uso correcto de ValueTasks
Categoría Confiabilidad
La corrección interrumpe o no interrumpe Sin interrupción
Habilitado de forma predeterminada en .NET 10 Como sugerencia
Idiomas aplicables C# y Visual Basic

Causa

Una instancia de ValueTask devuelta tras una invocación a un miembro se utiliza de una forma que puede provocar excepciones, corrupción o un rendimiento deficiente.

Descripción de la regla

ValueTask instancias devueltas de las invocaciones de miembro están diseñadas para ser esperadas directamente. Los intentos de consumir un ValueTask varias veces o de acceder directamente a su resultado antes de que se sepa que se ha completado pueden producir una excepción o corrupción de datos. Que se omita un ValueTask probablemente indica que se trata de un error funcional y puede degradar el rendimiento.

Cómo corregir infracciones

En general, deberían esperarse directamente los ValueTasks en lugar de descartarlos o almacenarlos en otras ubicaciones, como variables locales o campos.

Cuándo suprimir las advertencias

En el caso de los objetos ValueTask devueltos por llamadas de miembro arbitrarias, el autor de la llamada debe asumir que ValueTask debe consumirse (es decir, esperarse) una única vez. Sin embargo, si el desarrollador controla también el miembro que se invoca y tiene un conocimiento completo de su implementación, es posible que el desarrollador sepa que se puede suprimir la advertencia, por ejemplo, si el objeto ValueTask devuelto siempre encapsula un objeto Task.

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;

        // ...
    }
}

Supresión de una advertencia

Si solo quiere suprimir una única infracción, agregue directivas de preprocesador al archivo de origen para deshabilitar y volver a habilitar la regla.

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

Para deshabilitar la regla de un archivo, una carpeta o un proyecto, establezca su gravedad en none del archivo de configuración.

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

Para obtener más información, consulte Procedimiento para suprimir advertencias de análisis de código.

Consulte también