✅ Confused about Asynchronous Programming
I have been reading about Asynchronous programming for a long time but the concepts are not going through me.
From what I learnt, one way of calling async tasks is like this:
Okay so I understand this one. A task is started, some other work is done, and then the task is asked to return the result.
But what about this one:
Now how is this different from calling the method synchronously? We called the task and are now waiting for it to finish the next moment.
Also, some articles say that the
await
keyword suspends the execution of the current method and returns the control to the caller. From what I understand, its like:
The 1
will be printed to the console before 2
. But its not the case.
Please explain... 😭37 Replies
You're right, using
await
immediately after getting a task object does not make that code asynchronous. That code at the end is almost correct, but I think it should be like this:
This way, the 1 will be printed before awaiting, so it happens at the same time as the other task, making it asynchronous.So is it only truly asynchronous when used the way I wrote in the first code block?
If, say, in a winforms application, in an async button click event, I make it await a long task, will the UI block? If not, why?
I haven't worked much with WinForms, but if I recall correctly, it never awaits your event handlers. So the UI can be processed asynchronously while the task is busy.
Oh now I see
But if its like that, then why can't we use blocking code in the event handlers
This discussion is mis-using the term asyncrhonous to mean concurrent I think.
How are they different?
Oh, yeah I may have messed up the terminology
async means the original thread can do other work while the async operation is in flight.
concurrent means two things are in progress at the same time.
So is this assumption correct?
Both are async.
The second version is logically sequential.
The first version is logically concurrent.
When we await a task, it pauses the current function (and it can't do anything else). isn't this what blocking is?
No
This is something a lot of people struggle with.
When you await, the function is "logically blocking" meaning that the next line of code doesn't run until the async operation completes. But it's not actually blocking a thread.
The thread that the original await was running on can be used to do more work while the async operation is in progress. For instance, it gets returned to the thread pool in a web server to handle other requests. Or it's the UI thread in a UI application and it can process other UI events to repaint the window or whatever.
Eventually, the async operation completes. Now the code after the await is scheduled to run, but potentially on some completely different thread than the original one.
The fact that the original thread was released to go do other stuff while the async operation was in flight is why we say async is non-blocking.
Makes things much clear
When you await something, the async machinery wires up a continuation that will get run eventually when the async operation finishes. It's all part of the async state machine that is used. If you are interested there are detailed blog posts that go into very explicit detail about how this all works.
But if you just want to use async, hopefully what I explained will clarify what's happening at a high level.
Also if you want more material on this, I did a video on this topic:
https://youtu.be/8lUs9ukVrFY
C# Community Discord
YouTube
Solution1: Threads, Tasks and more with Mike Treit
This presentation recaps some of the basics of writing code that makes use of threads, tasks and asynchronous features in C#. It is a modified version of a talk the author has given to his team at Microsoft.
This is an intermediate level talk aimed at developers still learning how to write parallel and async code in C#.
Yes, it was very helpful.
I am still confused about this one thing. When we await a function, is it really needed that the function should use other asynchronous functions? Since its already in async state, we can use all synchronous functions?
Anything that you call inside an async function that is a synchronous call blocks the thread the function is currently executing on. But if the synchronous calls are cheap it's fine. If they are doing network I/O or other stuff that is slow, those should also be async.
An async method is like any other method until it gets to an await.
Then it does the async thing and the thread it was running on can do other stuff.
Then the continuation runs when the await finishes. Now we are back in the same state. The continuation runs like any other method until another await happens or it returns.
So if the thread is doing something else, where does the async method gets executed?
Sounds like you need to read $nothread
There Is No Thread
This is an essential truth of async in its purest form: There is no thread.
ou
You said async method but I think you meant async operation.
Yes
Ultimately at some point you get to the point where the operating system is going to kick off an async operation at the hardware level. That usually involves something like a hardware interrupt that will interrupt the CPU when the async I/O is done and the OS then schedules that operation to be completed.
makes sense
That stuff is happening down in kernel mode (where there aren't really threads in the sense you tend to think of them) and that's why the user mode thread can be put to work to do other stuff until the kernel comes back and says "ok we're done."
ah
That is much better
"The await keyword is used within an async method to temporarily suspend its execution and yield control back to the calling method until the awaited task is completed."
What does it mean by yield control back to the calling method?
By control I am understand something like the EIP pointer in x32.
It just means that the method returns at that point.
Returns a task to the caller.
The calling method can choose to do whatever it wants with that task.
Oh, it returns the task but doesn't go to the next instruction?
Right
understood
Basically you can think of every await as ending the method and the code after the await is the start of a new method.
Right
What async and await does is hide that detail from you and make it look like one big method.
That was all I could think of right now 😉
Thanks for helping!
Unknown User•10mo ago
Message Not Public
Sign In & Join Server To View
Use the /close command to mark a forum thread as answered