Давайте розглянемо цей дуже простий метод асинхронізації:
static async Task myMethodAsync()
{
await Task.Delay(500);
}
Коли я компілюю це за допомогою VS2013 (попередній компілятор Roslyn), сформований автомат-стан є структурою.
private struct <myMethodAsync>d__0 : IAsyncStateMachine
{
...
void IAsyncStateMachine.MoveNext()
{
...
}
}
Коли я компілюю його з VS2015 (Roslyn), згенерований код такий:
private sealed class <myMethodAsync>d__1 : IAsyncStateMachine
{
...
void IAsyncStateMachine.MoveNext()
{
...
}
}
Як бачите, Roslyn генерує клас (а не структуру). Якщо я добре пам'ятаю, перші реалізації підтримки async / await у старому компіляторі (я думаю, CTP2012) також генерували класи, а потім його було змінено на struct з причин продуктивності. (у деяких випадках ви можете повністю уникнути боксу та розподілу купи ...) (Див. це )
Хтось знає, чому це знову змінили в Росліні? (Я не маю жодних проблем з цим, я знаю, що ця зміна прозора і не змінює поведінку будь-якого коду, мені просто цікаво)
Редагувати:
Відповідь від @Damien_The_Unbeliever (і вихідний код :)) imho все пояснює. Описана поведінка Roslyn стосується лише побудови налагодження (і це потрібно через обмеження CLR, зазначене в коментарі). У Release він також генерує структуру (з усіма перевагами цього ..). Отже, це видається дуже розумним рішенням для підтримки редагування та продовження та кращої продуктивності у виробництві. Цікаві речі, дякую за всіх, хто брав участь!
async
Методи майже завжди мають справжню асинхронну точку - таку,await
яка дає контроль, що вимагатиме того, щоб структура все одно була позначена. Я вважаю, що структури лише зменшать тиск на пам’ять дляasync
методів, які випадково працюють синхронно.