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; }
Inside an async function, you can use the await keyword before a call to a function that returns a promise. This makes the code wait at that point until the promise is settled, at which point the fulfilled value of the promise is treated as a return value, or the rejected value is thrown.
“async” keyword needs to be updated in front of functions that contain ”await” keyword to notify that the result might be available after a certain delay since we are explicitly making the main thread wait until the promise has been resolved. Await and Async has introduced synchronous behavior to the Execution.
The async and await keywords enable asynchronous, promise-based behavior to be written in a cleaner style, avoiding the need to explicitly configure promise chains. Async functions may also be defined as expressions.
The word “async” before a function means one simple thing: a function always returns a promise. Other values are wrapped in a resolved promise automatically. So, async ensures that the function returns a promise, and wraps non-promises in it.
When using async
and await
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:
public async Task MyMethodAsync() { Task<int> longRunningTask = LongRunningOperationAsync(); // independent work which doesn't need the result of LongRunningOperationAsync can be done here //and now we call await on the task int result = await longRunningTask; //use the result Console.WriteLine(result); } public async Task<int> LongRunningOperationAsync() // assume we return an int from this long running operation { await Task.Delay(1000); // 1 second delay return 1; }
OK, so what happens here:
Task<int> longRunningTask = LongRunningOperationAsync();
starts executing LongRunningOperation
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 the longRunningTask
is done then a thread from the ThreadPool (can be any thread) will return to MyMethodAsync()
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 the await 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 a Task.Delay(1000)
involved.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With