Consideremos este método asincrónico muy simple:
static async Task myMethodAsync()
{
await Task.Delay(500);
}
Cuando compilo esto con VS2013 (compilador anterior a Roslyn), la máquina de estado generada es una estructura.
private struct <myMethodAsync>d__0 : IAsyncStateMachine
{
...
void IAsyncStateMachine.MoveNext()
{
...
}
}
Cuando lo compilo con VS2015 (Roslyn), el código generado es este:
private sealed class <myMethodAsync>d__1 : IAsyncStateMachine
{
...
void IAsyncStateMachine.MoveNext()
{
...
}
}
Como puede ver, Roslyn genera una clase (y no una estructura). Si recuerdo correctamente, las primeras implementaciones del soporte async / await en el compilador antiguo (CTP2012 supongo) también generaron clases y luego se cambió a estructura por razones de rendimiento. (en algunos casos puede evitar por completo el boxeo y la asignación de pila…) (Vea esto )
¿Alguien sabe por qué se volvió a cambiar esto en Roslyn? (No tengo ningún problema al respecto, sé que este cambio es transparente y no cambia el comportamiento de ningún código, solo tengo curiosidad)
Editar:
La respuesta de @Damien_The_Unbeliever (y el código fuente :)) en mi humilde opinión lo explica todo. El comportamiento descrito de Roslyn solo se aplica a la compilación de depuración (y eso es necesario debido a la limitación CLR mencionada en el comentario). En Release también genera una estructura (con todos los beneficios de eso ..). Así que esta parece ser una solución muy inteligente para admitir tanto Editar como Continuar y mejorar el rendimiento en producción. Cosas interesantes, ¡gracias a todos los que participaron!
async
Los métodos casi siempre tienen un verdadero punto asincrónico,await
que produce control, lo que requeriría que la estructura esté enmarcada de todos modos. Creo que las estructuras solo aliviarían la presión de la memoria para losasync
métodos que se ejecutaron sincrónicamente.