I was reading about async/await
keywords and I've read that:
When the flow of logic reaches the await token, the calling thread is suspended until the call completes.
Well, I've created a simple windows forms application
, placed two labels, a button and a textbox and I wrote the code:
private async void button1_Click(object sender, EventArgs e)
{
label1.Text = Thread.CurrentThread.ThreadState.ToString();
button1.Text = await DoWork();
label2.Text = Thread.CurrentThread.ThreadState.ToString();
}
private Task<string> DoWork()
{
return Task.Run(() => {
Thread.Sleep(10000);
return "done with work";
});
}
What I don't understand is that when I click the button, the label1 will have the text Running
and the label will have the same text only after 10 seconds, but in these 10 seconds I was able to enter the text in my textbox, so it seems that the main thread is running...
So, how does the async/await works?
here is a "screenshot" from the book:
Regards
I've read that: When the flow of logic reaches the await token, the calling thread is suspended until the call completes.
Where did you read that nonsense? Either there is some context there that you're not quoting, or you should stop reading whatever text it is that contained this. The point of await is to do the opposite of that. The point of await is to keep the current thread doing useful work while the asynchronous task is in flight.
UPDATE: I downloaded the book you referenced. Absolutely everything in that section is wrong. Throw this book away and buy a better book.
What I don't understand is that when I click the button, the label1 will have the text Running and the label will have the same text only after 10 seconds, but in these 10 seconds I was able to enter the text in my textbox, so it seems that the main thread is running...
That's correct. Here's what happens:
label1.Text = Thread.CurrentThread.ThreadState.ToString();
The text is set.
button1.Text = await DoWork();
A bunch of stuff happens here. What happens first? DoWork
is called. What does it do?
return Task.Run(() => { Thread.Sleep(10000);
It grabs a thread out of the thread pool, puts that thread to sleep for ten seconds, and returns a task representing the "work" being done by that thread.
Now we are back here:
button1.Text = await DoWork();
We have a task in hand. Await first checks the task to see if it is already complete. It is not. Next it signs up the remainder of this method as the continuation of the task. Then it returns to its caller.
Hey, what is its caller? How did we get here anyways?
Some code called this event handler; it was the event loop that is processing Windows messages. It saw a button was clicked and dispatched to the click handler, which has just returned.
Now what happens? The event loop keeps running. Your UI keeps on running nicely, as you noticed. Eventually that thread ticks off ten seconds and the task's continuation is activated. What does that do?
That posts a message into the Windows queue saying "you need to run the rest of that event handler now; I have the result you were looking for."
The main thread event loop eventually gets to that message. So the event handler picks up where it left off:
button1.Text = await DoWork();
The await now extracts the result from the task, stores it in the button text, and returns back to the event loop.