接口IAsyncStateMachine只能由编译器使用,用于生成异步方法的状态机。接口使用堆分配的副本(来自msdn)配置状态机。
我使用SetMachineState来反编译代码并发现生成的状态机,并提到ILSpy函数的实现总是空的,如下所示

[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
    }
}

还有一件事,生成的状态机是一个SetMachineState而不是一个class的。
所以,问题是:struct接口的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);
    }
}

10-08 08:47