Async wait: is the main topic paused?

I read about async/await keywords and I read that:

When the logic thread reaches the wait token, the calling thread is suspended until the call ends.

Well, I created a simple windows forms application , placed two labels, a button and a text box, 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"; }); } 

I don’t understand that when I click the button, 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 the text box, so it seems that the main thread is working. ..

So how does async / await work?

here is a screenshot from the book: enter image description here

Hi

+6
source share
3 answers

I read that: when the logic thread reaches the wait token, the calling thread pauses until the call ends.

Where did you read this bullshit? There is some context there that you are not quoting, or you should stop reading any text that contains this. The expected point is the opposite . The expected point is to keep the current thread useful while the asynchronous task is in flight.

UPDATE: I downloaded the book you referenced. Absolutely everything in this section is incorrect. Drop this book and buy the best book.

I don’t understand that when I click the button, 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 text into my text box, so it seems that the main thread is started. ..

It is right. Here's what happens:

  label1.Text = Thread.CurrentThread.ThreadState.ToString(); 

The text is set.

  button1.Text = await DoWork(); 

A lot of things are happening here. What happens first? DoWork . What is he doing?

  return Task.Run(() => { Thread.Sleep(10000); 

It grabs a thread from the thread pool, puts the thread to sleep for ten seconds, and returns a task representing the "work" performed by that thread.

Now we are back here:

  button1.Text = await DoWork(); 

We have a task. Waiting first checks the task to make sure it is already completed. Is not. He then signs the remainder of this method as a continuation of the task. He then returns to the caller.

Hey, what's his call? How did we get here?

Some code called this event handler; it was an event loop processing windows messages. He saw that a button had been pressed and sent to the click handler that had just returned.

Now what is going on? The event loop continues to work. As you noticed, your user interface works well. In the end, this branch goes out for ten seconds and the continuation of the task is activated. What does it do?

It sends a message to the Windows queue, saying "you need to run the rest of this event handler, I have the result you were looking for."

The main flow event loop ends up in this message. Therefore, the event handler selects where it stopped:

  button1.Text = await DoWork(); 

Waiting now extracts the result from the task, saves it in the button text and returns to the event loop.

+15
source

async / await creates the end machines that handle the sequel for you. A very crude equivalent (without many functions) is an explicit continuation method, for example:

 private void button1_Click_Continuation(string value) { button1.Text = value; label2.Text = Thread.CurrentThread.ThreadState.ToString(); } private void button1_Click(object sender, EventArgs e) { label1.Text = Thread.CurrentThread.ThreadState.ToString(); DoWork(button1_Click_Continuation); } private void DoWork(Action<string> continuation) { Task.Run(() => { Thread.Sleep(10000); continuation("done with work"); }); } 

Note that I'm still using Task.Run to run in a separate thread. Please note that this version has no way to track progress (while the original can change the return value of button1_Click to Task to see if it is complete or not).

In addition to the conversion above, the system is reasonable as to whether the Task started in the user interface thread and again accesses the user interface thread to ensure that everything works as you expect. This is probably the main thing that you do not understand, but the expansion of the aspect of the state apparatus sometimes explains what asyc / await means (instead of leaving it as mystical).

0
source

By writing await , you say: stop executing the method at that moment, wait for DoWork and only then continue.

Asynchronous programming with asynchronous and waiting (C #) in the section “What happens in the Async method” has a step-by-step explanation with the image about what happens in the async method.

An even better explanation is wait (link to C #) . Take a look at the comments for WaitSynchronously and WaitAsynchronouslyAsync below.

The article also says (focus):

The wait statement is applied to a task in an asynchronous method to pause the method until the expected task completes. The task is an ongoing job.

 private async void button1_Click(object sender, EventArgs e) { // Call the method that runs asynchronously. string result = await WaitAsynchronouslyAsync(); // Call the method that runs synchronously. //string result = await WaitSynchronously (); // Display the result. textBox1.Text += result; } // The following method runs asynchronously. The UI thread is not // blocked during the delay. You can move or resize the Form1 window // while Task.Delay is running. public async Task<string> WaitAsynchronouslyAsync() { await Task.Delay(10000); return "Finished"; } // The following method runs synchronously, despite the use of async. // You cannot move or resize the Form1 window while Thread.Sleep // is running because the UI thread is blocked. public async Task<string> WaitSynchronously() { // Add a using directive for System.Threading. Thread.Sleep(10000); return "Finished"; } 
0
source

All Articles