接口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);
}
}