Microsoft's official MSDN says async and await are "asynchronous", but many people (including the author himself) have some misconceptions to clarify: why is the await statement not executed after? Isn't it asynchronous?
Let's start with a sample code like this:
?
123456789101112131415161718 |
public partial class Form1 : Form
{
public async Task Processing()
{
await Task.Delay(5000);
label1.Text =
"Succuessful"
;
}
public Form1()
{
InitializeComponent();
}
private async
void button1_Click(
object sender, EventArgs e)
{
await Processing();
MessageBox.Show(
"Button‘s event completed"
);
}
}
|
Many people (including the author) begin to think that async is like multithreading, that when an await occurs, a thread executes the task in the background, and then the main thread (this is the UI thread) automatically executes the later part (that is, the message box that pops up "button's event completed").
In fact, this understanding is wrong. The nature of async and await is actually the "iterative" wait for "yield return" and "LINQ". We should be clear: that is, you wrote the LINQ statement:
?
1234567 |
var results = from …… select ……; foreach (var r in results) { …… } |
When you place a breakpoint you will notice that the results is not executed immediately until it is used in the results (in the case of foreach here) to be executed (at which point the yellow track will be folded back to Var results ...). Here, and then wait until the results execution is complete before actually entering foreach for execution).
Therefore, this "iterative" asynchronous operation of Async/await and LINQ is analogous. Just because the essence of async/await is to return a task, and the task is asynchronous (because the task is essentially a thread), the background will actually open a thread to perform the task when the method with await is actually executed (when using the Async method). At this point the main thread waits until it finishes executing (the Iscomplete property is true). So the interface is not stalling.
So, await is an asynchronous wait for a task, not what we call an "asynchronous operation"; compare it to LINQ, and you'll see that LINQ executes in the same order as it does, except that LINQ doesn't wait asynchronously (of course!). There is no thread to open ... )。
We can further contrast this:
LINQ: Variable = LINQ statement (expression)
Wait until the LINQ variable is used to actually execute the LINQ statement at the LINQ statement.
Async wait: variable = Async method
Wait until the asynchronous method is used to await+ the asynchronous method, the open thread actually executes the Async method, the main threads are suspended (but not causing the interface to die) until the child thread task is fully executed.
In LINQ, you can use the extension method if you need to do it now:
var results = (from ...... ...). ToList (); Because this LINQ statement is used immediately, it is executed immediately.
Similarly, asynchronous waits can become wait-like synchronous waits:
?
12345 |
private async void button1_Click( object sender, EventArgs e) { Processing().GetAwaiter().GetResult(); MessageBox.Show( "Button‘s event completed" ); } |
Because processing originally returned a task, you can also use wait to synchronize the wait.
"Reprint Asynchronous Misunderstanding"