Considere el siguiente método:

public async Task<string> GetNameOrDefaultAsync(string name)
{
    if (name.IsNullOrDefault())
    {
        return await GetDefaultAsync();
    }

    return name;
}

Cuando se proporciona name, no se producirá ninguna espera en la ejecución del método, pero este método se compilará correctamente.

Sin embargo, este método producirá la advertencia de compilación que se muestra a continuación:

public async Task<string> GetDefaultAsync()
{
    return "foobar";
}

[CS1998] This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

¿Por qué GetNameOrDefaultAsync puede regresar sin esperar nunca y no generar una advertencia del compilador, pero GetDefaultAsync debe esperar para compilar?

¿Sería una mejora hacer lo siguiente ?:

public async Task<string> GetNameOrDefaultAsync(string name)
{
    if (name.IsNullOrDefault())
    {
        return await GetDefaultAsync();
    }

    return await Task.FromResult(name);
}

Aquí no tendríamos rutas de ejecución que no await algo.

2
Benjamin Leeds 7 may. 2021 a las 18:02

1 respuesta

La mejor respuesta

¿Por qué GetNameOrDefault puede regresar sin esperar y no generar una advertencia del compilador?

Debido a que hay rutas de ejecución que usan await, y para poder usar await, el método debe ser async.

Por otro lado, si no rutas que usan await, la palabra clave async es claramente superflua, de ahí la advertencia.

¿Sería una mejora hacer lo siguiente? return await Task.FromResult(name);

No, Task.FromResult simplemente envuelve name en un objeto Task, que está en un estado completo, lo que significa que await lo desenvuelve de nuevo inmediatamente.

Esto asigna un Task innecesariamente y no logra nada.


Aparte, si name.IsNullOrDefault() es casi siempre false, es decir, usar await es la excepción, no la regla, puede reducir las asignaciones usando ValueTask en su lugar: ¿Por qué usar Task sobre ValueTask en C #?

5
Johnathan Barclay 7 may. 2021 a las 15:23