Consideriamo questo metodo asincrono molto semplice:
static async Task myMethodAsync()
{
await Task.Delay(500);
}
Quando lo compilo con VS2013 (compilatore pre Roslyn), la macchina a stati generata è una struttura.
private struct <myMethodAsync>d__0 : IAsyncStateMachine
{
...
void IAsyncStateMachine.MoveNext()
{
...
}
}
Quando lo compilo con VS2015 (Roslyn) il codice generato è questo:
private sealed class <myMethodAsync>d__1 : IAsyncStateMachine
{
...
void IAsyncStateMachine.MoveNext()
{
...
}
}
Come puoi vedere Roslyn genera una classe (e non una struttura). Se ricordo bene le prime implementazioni del supporto async / await nel vecchio compilatore (CTP2012 immagino) hanno anche generato classi e poi è stato cambiato in struct per motivi di prestazioni. (in alcuni casi puoi evitare completamente la boxe e l'allocazione dell'heap ...) (Vedi questo )
Qualcuno sa perché questo è stato cambiato di nuovo a Roslyn? (Non ho alcun problema al riguardo, so che questa modifica è trasparente e non cambia il comportamento di nessun codice, sono solo curioso)
Modificare:
La risposta di @Damien_The_Unbeliever (e il codice sorgente :)) imho spiega tutto. Il comportamento descritto di Roslyn si applica solo per la build di debug (ed è necessario a causa della limitazione CLR menzionata nel commento). In Release genera anche una struttura (con tutti i vantaggi di ciò ..). Quindi questa sembra essere una soluzione molto intelligente per supportare sia Modifica che Continua e prestazioni migliori in produzione. Roba interessante, grazie per tutti coloro che hanno partecipato!
async
i metodi hanno quasi sempre un vero punto asincrono,await
che fornisce il controllo, il che richiederebbe comunque che la struttura sia boxata. Credo che le strutture allevierebbero la pressione della memoria solo per iasync
metodi che si sono verificati in modo sincrono.