¿Por qué una función asíncrona sin esperar genera una advertencia del compilador?

¿Alguien puede explicar por qué se requiere que las funciones asíncronas en C # 5 tengan al menos 1 en espera? No puedo encontrar una razón/explicación clara.

Por requerido, quiero decir que el compilador advierte cuando una función asíncrona no tiene llamadas en espera dentro de ella, pero no arroja un error de compilación.

Desde esta respuesta:

De manera similar, un método marcado como asíncrono debe tener al menos una espera. En una espera, el tiempo de ejecución guardará el estado del subproceso actual y la pila de llamadas, realizará la llamada asincrónica y regresará al ciclo de mensajes del tiempo de ejecución para manejar el siguiente mensaje y mantener la aplicación receptiva. Cuando se completa la operación asíncrona, en la próxima oportunidad de programación, la pila de llamadas para aumentar la operación asíncrona se vuelve a insertar y continúa como si la llamada fuera síncrona.

Pero desde msdn:

Si el método no contiene una expresión o declaración de espera, entonces se ejecuta de forma síncrona. Una advertencia del compilador le alerta sobre cualquier método asíncrono que no contenga espera porque esa situación podría indicar un error.

¿Qué tipo de error ocurre que justifica que se trate de una advertencia del compilador en lugar de solo un uso recomendado?

preguntado el 11 de abril de 13 a las 04:04

1 Respuestas

MSDN tiene una buena descripción para esta advertencia: Advertencia del compilador (nivel 1) CS4014. La buena cita de ella será:

En la mayoría de los casos, ese comportamiento no es el esperado.

Creo que la razón principal por la que existe esta advertencia es que async/await no es realmente obvio, y los desarrolladores suelen cometer errores como los que describiré a continuación.

Por ejemplo, tienes un método que hace algo pesado durante varios segundos:

public int DoSomething()
{
    int sum = 0;

    for (int i = 0; i < 10; i++)
    {
        sum += i;
        Thread.Sleep(1000);
    }

    return sum;
}

Escuchaste sobre async y await en algún lugar y quieres probarlos. Y así es como muy a menudo las personas piensan que moverán todo a un segundo plano (tal vez no a menudo, pero pensé que así es como funciona antes de leer más documentación, por lo que podemos contar al menos a mí):

public async Task<int> DoSomething()
{
    int sum = 0;

    for (int i = 0; i < 10; i++)
    {
        sum += i;
        Thread.Sleep(1000);
    }

    return sum;
}

Crees que el problema está resuelto, pero la advertencia te dice que sin await no deberías usar async, porque simplemente no hace nada, todo su código se ejecutará sincrónicamente, la última muestra con async es similar al siguiente código:

public Task<int> DoSomething()
{
    int sum = 0;

    for (int i = 0; i < 10; i++)
    {
        sum += i;
        Thread.Sleep(1000);
    }

    return Task.Result<int>(sum);
}

Donde haces todo en el mismo contexto, que llama a este método.

Entonces, la razón principal de esta advertencia es que creo que la gente sabe que probablemente usen async incorrecto y este es un momento para leer la documentación.

Respondido 11 Abr '13, 06:04

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.