Давайте рассмотрим этот очень простой асинхронный метод:
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) также генерировали классы, а затем он был изменен на структуру из соображений производительности. (в некоторых случаях можно полностью избежать боксов и выделения кучи…) (См. это )
Кто-нибудь знает, почему это снова поменяли в Roslyn? (У меня нет проблем с этим, я знаю, что это изменение прозрачное и не меняет поведения какого-либо кода, мне просто любопытно)
Редактировать:
Ответ от @Damien_The_Unbeliever (и исходный код :)) imho все объясняет. Описанное поведение Roslyn применяется только для отладочной сборки (и это необходимо из-за ограничения CLR, упомянутого в комментарии). В Release он также генерирует структуру (со всеми преимуществами этого ..). Таким образом, это кажется очень умным решением для поддержки как редактирования, так и продолжения, а также повышения производительности в производственной среде. Интересный материал, спасибо всем, кто участвовал!
async
методы почти всегда имеют истинную асинхронную точку - точку,await
которая дает управление, которое в любом случае потребует упаковки структуры. Я считаю, что структуры только уменьшат давление на память дляasync
методов, которые выполняются синхронно.