From my understanding one of the main things that async
and await
do is to make code easy to write and read – but is using them equal to spawning background threads to perform long duration logic?
I'm currently trying out the most basic example. I've added some comments inline. Can you clarify it for me?
// I don't understand why this method must be marked as `async`.
private async void button1_Click(object sender, EventArgs e)
{
Task<int> access = DoSomethingAsync();
// task independent stuff here
// this line is reached after the 5 seconds sleep from
// DoSomethingAsync() method. Shouldn't it be reached immediately?
int a = 1;
// from my understanding the waiting should be done here.
int x = await access;
}
async Task<int> DoSomethingAsync()
{
// is this executed on a background thread?
System.Threading.Thread.Sleep(5000);
return 1;
}
Best Answer
When using
async
andawait
the compiler generates a state machine in the background.Here's an example on which I hope I can explain some of the high-level details that are going on:
OK, so what happens here:
Task<int> longRunningTask = LongRunningOperationAsync();
starts executingLongRunningOperation
Independent work is done on let's assume the Main Thread (Thread ID = 1) then
await longRunningTask
is reached.Now, if the
longRunningTask
hasn't finished and it is still running,MyMethodAsync()
will return to its calling method, thus the main thread doesn't get blocked. When thelongRunningTask
is done then a thread from the ThreadPool (can be any thread) will return toMyMethodAsync()
in its previous context and continue execution (in this case printing the result to the console).A second case would be that the
longRunningTask
has already finished its execution and the result is available. When reaching theawait longRunningTask
we already have the result so the code will continue executing on the very same thread. (in this case printing result to console). Of course this is not the case for the above example, where there's aTask.Delay(1000)
involved.