Async/Await in C# is syntax sugar for StateMachine
State Machine and it’s internal working explained
This article assumes you have basic understanding or Asynchronous Programming with C# using Async/Await. Missing Basics of asynchronous programming and it’s benefits? You can start with this Blog Series.
In very simple terms the async/await
is a sort of syntax sugar. Each async
method will be translated into a StateMachine
and then calling method use this StateMachine
to execute business logic.
Few people like to have theory first few people like to see code straightaway. I am planning to use a hybrid approach Where we will have a small dose of theory and then all code for State Machine (With some helpful comments) then we will try to draw a picture to explain the code execution flow inside a state machine.
Few Terms that is used throughout the post.
WorkerFunction
: Method will be the actual asynchronous work need to be done.CallingFunction
: Method that will call theWorkerFunction
.FirstCall
: First time theMoveNext
ofStateMachine
is called (Synchronous Flow
)WakeUpCall
: After theawait
results are available and code continue from where it left.Sort of callback.
If you cannot make any sense of these terms don’t worry they will be lot more understandable as we progress in the post.
What happen when we compile the code (Brief — Theory)
We take our code snippet and paste it into http://Sharplab.io
and then it will generate a compiled code for the code snippet. These are the few things that compiler
will generate for our asynchronous code.
- Compiler will generate a
StateMachine
(IAsyncStateMachine) code for theWorkerFunction
. - Move the actual Logic of
WorkerFunction
toMoveNext
function of state machine. - Create variable inside
StateMachine
to maintain variable needed forStateMachine
operation. CallingFunction
is changed to create a new instance ofStateMachine
- Call Start on one of the
StateMachine
TaskMethodGenerator (More details below) inCallingFunction
Time to see some code
Here is a very simple piece of code which make use of async/await
keyword. I am keeping the code sample complexity to bare minimum as our focus is on understanding the working of async/await
not the possible applications of async/await
. That deserves a blog post on it’s own.
I pasted this code to http://sharplab.io
and compiled the code in the Debug
and the output generated was something like below.
I added few comments to the code generated to help with Understanding the flow of execution.
Explanation of the Code above
If you have already read through the code sample above and still things don’t make complete sense.
Let me draw a picture this time. This may help with understanding of the code execution flow.
I tried to use some color pattern please let me know in comments if that helped in understanding the flow of execution.
- All the boxes with Red Border will be executed on the both
FirstCall
andWakeUpCall
. - Blue Boxes will be executed on
FirstCall
only - Green Boxes may Get Executed on
FirstCall
if awaiter is completed already but highly unlikely this flow is there of optimizations. - Green Boxes will be executed on
WakeUpCall
for sure in case of there are no errors or exception
For this blog post i am considering happy paths. Please let me know if you are interested in reading more about the exception scenarios also.
See you soon
I will be back soon with a post about How we can refactor an application from synchronous to asynchronous. We will refactor the repository layer first. Then we will update the controllers consuming these repositories. Finally we will update our unit tests for asynchronous controller actions.