Interface IAsyncStateMachine
can be used only by compiler, and is used in generating state machine for async methods. Interface has SetMachineState
- configures the state machine with a heap-allocated replica(from msdn).
I used ILSpy
to decompile code and discover generated state machine and mentioned that implementation of SetMachineState
function is always empty, like this
[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
}
}
One more thing, generated state machine is a class
not a struct
as stated everywhere.
So, the question is: What the purpose of SetStateMachine
function of IAsyncStateMachine
interface, where is it used?
Original async function:
private static async Task<int> GetResult()
{
var task = GetSomeData();
DoSomeWork();
return await task;
}
This happens because you're looking at a debug
build and not a release
one.
Making the state-machine a struct is a compiler optimization. It enables not allocating memory when the awaitable is already completed when awaited. That optimization isn't necessary while debugging and it makes implementing debugging features in Visual Studio harder.
If you look at the same code compiled in release
the state-machine will indeed be a struct and the SetStateMachine
method will not be empty as this is the method that moves the state-machine from the stack to the heap:
[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);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With