让我们考虑一下这个非常简单的异步方法:
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()
{
...
}
}
如您所见,罗斯林生成一个类(而不是一个结构)。如果我没有记错的话,旧编译器中异步/等待支持的第一个实现(我猜是CTP2012)也会生成类,然后出于性能原因将其更改为struct。(在某些情况下,您可以完全避免装箱和分配堆…)(请参阅此)
有谁知道为什么在罗斯林再次改变了这一点?(对此我没有任何问题,我知道此更改是透明的,不会更改任何代码的行为,我很好奇)
编辑:
来自@Damien_The_Unbeliever(和源代码:))的答案可以解释一切。Roslyn的描述的行为仅适用于调试构建(由于注释中提到了CLR限制,因此需要这样做)。在Release中,它还会生成一个结构(具有所有好处。)。因此,这似乎是一个非常聪明的解决方案,可以同时支持“编辑”和“继续”以及更好的生产性能。有趣的东西,谢谢大家参加!
async
方法几乎总是具有真正的异步点-await
产生控制点,无论如何都将需要对结构进行装箱。我相信结构只会减轻async
碰巧同步运行的方法的内存压力。