IAsyncStateMachine.SetStateMachine 的目的是什么?

What is the purpose of IAsyncStateMachine.SetStateMachine?

接口IAsyncStateMachine只能由编译器使用,用于为异步方法生成状态机。接口具有 SetMachineState - 使用堆分配的副本(来自 msdn)配置状态机。

我使用 ILSpy 反编译代码并发现生成的状态机,并提到 SetMachineState 函数的实现总是空的,像这样

[CompilerGenerated]
private sealed class <GetResult>d__1 : IAsyncStateMachine
{
    //some fields to hold state

    void IAsyncStateMachine.MoveNext()
    { ... }

    [DebuggerHidden]
    void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine)
    {
        //Method is empty
    }
}

还有一件事,生成的状态机是 class 而不是到处都说的 struct

所以,问题是:IAsyncStateMachine接口的SetStateMachine函数的作用是什么,用在什么地方?

原来的异步函数:

private static async Task<int> GetResult()
{
    var task = GetSomeData();
    DoSomeWork();
    return await task;
}

发生这种情况是因为您正在查看 debug 版本而不是 release 版本。

使状态机成为一个结构体是一种编译器优化。它允许在等待时等待已完成时不分配内存。调试时不需要进行优化,这使得在 Visual Studio 中实现调试功能变得更加困难。

如果您查看在 release 中编译的相同代码,状态机确实是一个结构并且 SetStateMachine 方法不会为空,因为这是移动状态的方法-机器从栈到堆:

[CompilerGenerated]
[StructLayout(LayoutKind.Auto)]
private struct <GetResult>d__1 : IAsyncStateMachine
{
    public AsyncTaskMethodBuilder<int> <>t__builder;
    ...

    [DebuggerHidden]
    void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine)
    {
        this.<>t__builder.SetStateMachine(stateMachine);
    }
}