Asynchronous Programming in C# Explained (Task.Run, Task.WaitAll, Async and Await)
Summary
TLDRThis script explains asynchronous programming using a relatable analogy of moving house and doing chores. It contrasts synchronous and asynchronous programming with C# examples, demonstrating how tasks can run in parallel without waiting for each other. The script further clarifies scenarios where tasks depend on each other, using 'Task.WaitAll' and 'await' keywords to synchronize. It also touches on the practical use of callbacks and async/await for a more straightforward, synchronous-like coding experience in asynchronous programming.
Takeaways
- 🏠 **Asynchronous Programming Defined**: Asynchronous programming allows for tasks to be performed without waiting for the completion of other tasks, similar to how you can pack while your house is being cleaned.
- 💻 **Synchronous vs Asynchronous**: Synchronous tasks must be completed in a specific order, whereas asynchronous tasks can be done in parallel without waiting for each other.
- 🛠️ **C# Implementation**: In C#, asynchronous programming is implemented using tasks, which can be run concurrently without blocking the main thread.
- 🔄 **Task.Run Usage**: `Task.Run` is used in C# to execute functions asynchronously, allowing for non-blocking code execution.
- 🔄 **Simulating Long-Running Tasks**: The `Sleep` method is used in C# to simulate long-running tasks, which is useful for demonstrating asynchronous behavior.
- 🔄 **Order of Execution**: The order of task execution in asynchronous programming can vary, as seen with the different outputs when running tasks concurrently.
- 🔗 **Dependency Management**: When tasks depend on each other, `Task.WaitAll` or `Task.WaitAny` can be used to ensure that dependent tasks are completed before proceeding.
- 🔄 **Callbacks in Asynchronous Programming**: Callbacks are used in C# to handle the results of asynchronous tasks once they are completed.
- 🔄 **Async and Await Keywords**: The `async` and `await` keywords in C# are used to simplify asynchronous programming, making it appear synchronous while still running tasks in parallel.
- 🔄 **Control Flow with Async/Await**: Using `async` and `await` allows developers to write asynchronous code that looks like synchronous code, maintaining a clear sequence of operations.
- 🔄 **Static Methods and Async**: Static methods can also be made asynchronous by using the `async` keyword, allowing for non-blocking calls within the method.
Q & A
What is asynchronous programming?
-Asynchronous programming is a programming paradigm where tasks can be executed concurrently without waiting for the completion of other tasks. It allows for tasks that are independent of each other to run in parallel, improving efficiency and performance.
How does the analogy of moving houses relate to asynchronous programming?
-The analogy of moving houses is used to illustrate the concept of asynchronous programming. Just as you can start packing your belongings while your new house is being cleaned or painted, asynchronous programming allows you to start new tasks while others are still running, without waiting for them to complete.
What is synchronous programming in the context of the script?
-Synchronous programming refers to the execution of tasks in a sequence where one task must complete before the next one begins. In the script, it is used to contrast with asynchronous programming, where tasks can be executed concurrently.
How is asynchronous programming implemented in C#?
-In C#, asynchronous programming is implemented using the `Task` class and the `async` and `await` keywords. The `Task` class allows for the execution of operations on separate threads, while `async` and `await` provide a way to write asynchronous code that looks and behaves more like synchronous code.
What is the purpose of the `Task.Run` method in C#?
-The `Task.Run` method is used to execute a method asynchronously. It allows the calling code to continue executing without waiting for the task to complete, which can improve the responsiveness of an application.
Why is the `await` keyword used in C#?
-The `await` keyword is used to pause the execution of the current method until the awaited task is completed. It allows for the continuation of the method after the awaited task has finished, providing a way to handle asynchronous operations in a more synchronous-like manner.
What is the difference between `Task.WaitAll` and `Task.WaitAny` in C#?
-`Task.WaitAll` is used to wait for all specified tasks to complete, while `Task.WaitAny` waits for any of the specified tasks to complete. In the script, `WaitAll` is used when a task depends on the completion of multiple other tasks.
How can you handle dependencies between tasks in C#?
-Dependencies between tasks can be handled by waiting for the completion of prerequisite tasks before starting a dependent task. This can be done using `await` to wait for the task to complete and then using its result as needed.
What is a callback function in the context of asynchronous programming?
-A callback function is a function that is called after another function has completed its execution. In the context of asynchronous programming, it is used to handle the result of an asynchronous operation once it has completed.
How does the `async` keyword simplify asynchronous programming in C#?
-The `async` keyword allows you to write asynchronous code that looks and behaves more like synchronous code. It enables the use of `await`, which allows you to pause the method execution until an awaited task is completed, making the code easier to read and maintain.
What is the significance of the order of task execution in the script?
-The order of task execution in the script demonstrates the non-deterministic nature of asynchronous programming. Since tasks can run concurrently, the order in which they complete and their results are printed can vary, depending on the duration of each task.
Outlines
📚 Introduction to Asynchronous Programming with Real-Life Example
The speaker introduces asynchronous programming by comparing it to real-life situations. They explain how certain tasks need to be done in a sequence, like moving houses, while other tasks can be done concurrently, like cleaning and packing. This sets the stage for understanding synchronous vs. asynchronous programming in C#. Synchronous programming is compared to tasks that must happen in order, while asynchronous programming allows tasks to run simultaneously.
💻 Demonstrating Synchronous Code Execution in C#
The speaker describes synchronous execution in C# using a simple example with three calculation functions. The functions are run one by one, demonstrating that the output appears in the exact sequence they were called. The key point is that these calculations do not depend on one another, and thus could run in parallel if done asynchronously. This section establishes the basic understanding of how synchronous code behaves.
⚙️ Transforming the Code to Asynchronous Execution
The speaker introduces C#'s task-based asynchronous programming. They demonstrate how to run the calculation functions asynchronously using `Task.Run`, leading to a different order of output. Since one calculation function simulates a longer-running task, the output order changes as faster functions complete first. This section emphasizes the non-blocking nature of asynchronous tasks and explains how parallel execution works.
🔄 Handling Task Dependencies in Asynchronous Code
The speaker explains how to handle dependencies between asynchronous tasks. Using a scenario where one calculation depends on the results of others, they introduce the `Task.WhenAll` method. The code ensures that certain calculations wait for others to complete before proceeding. This section shows how to maintain control over asynchronous tasks when outputs need to rely on prior results, ensuring correct execution order.
⏳ Managing Asynchronous Callbacks and Task Continuations
This section discusses using callbacks in asynchronous programming. The speaker explains how to trigger tasks to run after others have completed, using callbacks to pass results between tasks. They demonstrate how the asynchronous flow can still control task execution order, even when tasks run in parallel. This highlights how asynchronous tasks can remain dependent on each other while not blocking other executions.
🔀 Using `async` and `await` for More Intuitive Asynchronous Code
The speaker introduces the `async` and `await` keywords, simplifying asynchronous code to resemble synchronous programming. They create a new function using these keywords, explaining how `await` pauses the function execution until a task is complete. This allows developers to write code that looks sequential but runs asynchronously, making asynchronous programming easier to follow and maintain.
🔗 Final Thoughts on Asynchronous Programming
The speaker wraps up by combining all the previous concepts into a final example where tasks are run asynchronously but still follow a defined sequence using `async` and `await`. They emphasize how asynchronous code can manage both independent and dependent tasks. The section concludes with a demonstration of how this technique allows developers to control execution flow while benefiting from non-blocking, asynchronous behavior.
Mindmap
Keywords
💡Asynchronous Programming
💡Synchronous Programming
💡Task
💡Sleep
💡Callback
💡Await
💡Async
💡Concurrent
💡Dependency
💡Main Function
💡Thread
Highlights
Introduction to asynchronous programming and its comparison to daily life activities.
Explanation of synchronous programming with an example of moving house.
Illustration of how certain tasks can be done in parallel, like cleaning and packing a house.
Introduction to asynchronous programming in C#.
Explanation of how to implement asynchronous programming in C# using tasks.
Demonstration of running functions asynchronously with `Task.Run` and `async`/`await`.
Example of how the order of execution can change with asynchronous programming.
Explanation of how to handle dependencies between asynchronous tasks.
Use of `Task.WhenAll` to wait for multiple tasks to complete.
Example of a callback function in asynchronous programming.
Introduction to the `async` and `await` keywords in C#.
Explanation of how `async` and `await` can make asynchronous code look synchronous.
Example of creating an asynchronous function that waits for other tasks.
Demonstration of how to chain asynchronous tasks using `await`.
Explanation of how to create a static method that awaits the completion of other tasks.
Example of how to use `await` to control the flow of asynchronous tasks.
Final thoughts on asynchronous programming in C# and its practical applications.
Transcripts
hello everyone today I want to talk
about asynchronous programming first of
all what is asynchronous programming so
without going to the code let's examine
the daily life some of the actions we
can take one by one we have to take them
one by one
for example we buy a new house and we
move out of we move out from the own
house and we move in to the new house we
can't we have to follow the sequence of
this water we can't move out before buy
a new place otherwise we don't have any
place to to live and we can't move in
before we move out but some of the
actions we don't have to take them in a
particular order
for example after we we bought our new
house we need to ask someone to clean it
up to paint the wall or maybe we want to
make a new kitchen so we want to clean
that clean up the house but at the same
time we can start packing we don't have
to wait till the cleaning lab is
finished before we start packing we can
do that to them at the same time so this
in computer on language we can call it
asynchronous programming whereas this is
called synchronous programming right
let's take a look at the c-sharp codes
how asynchronous programming is
implemented in c-sharp
so before again before we examine how a
king Sinclair's framing works in c-sharp
let's take a look the codes that that
runs normally synchronously so we have
three calculation functions it doesn't
do any calculation just returns number
and the first one we're using sleep
throughout the sleep to simulate the
situation where this calculation takes a
longer time than the others and we have
this this is this is a calculation just
cause the other ones and it's called in
the main function that it's the entry
point of the console application so if
we run this application the lines of
code here will run one by one in this
water the water will not be messed up
has to be the SEC the first one runs and
then the second one and there's third
one so
as you can see it says calculating
result one calculation without two
culinary's all three so if we look at
the the calculation the three
calculation functions carefully we can
see that they don't actually depend on
each other
right they don't depend on each other at
all so there's no reason why we cannot
let them run in parallel and how do we
do that in c-sharp we have this
asynchronous programming functionality
introduced a long time ago so and that's
called something called task so we can
use tasks to run these functions
asynchronously and the way to do it is
to do tasks run and we can use slam for
expression so we can run the first one
and then we run the second one we're
doing this third one second one third
one
and let's give it a try
all right so this time the result looks
different
calculating result to calculating
results 3 in calculating result 1 y this
time the order is different because the
first time if you remember it says
calculating resultant one and then
result two and there is all three this
time wide result one becomes the last
one and then we look at the code the
result one has a sleep statement to
simulate that it's a long-running
process whereas result two and three
returns right away so that's why we see
this happens secondly this is oppisite
sec first firstly this is output
secondly and finally this one was output
so this tells us that at least the first
one was running while the second one is
there when a run was running so on the
reason why this third one still comes
secondly before after the second one was
because calculating calculate 2 was
started and then right away calculating
three start so because calculation to
takes like returns immediately so this
one still finishes before this one but
because calculate one takes three
seconds to finish so that's why we're
seeing that the output goes result to
first root of three secondly and the
result one right so let's is I'm in a
different scenario that let's say
calculation three depends on calculation
one and two okay
so let's put some parameter here
resolved
one result to and we're returning one
plus result - okay
and so in this case we cannot call it
this way because otherwise first of all
well first of all we cannot get the
parameters we cannot get the return
value from calculate one and calculate
two secondly read all three will run
before result one finishes so what
should we do in this case okay so in in
that case when you do something like
this
they return the tasks for the first two
and here we need to return the value
well yeah return the value and here we
just say we want to weigh for both task
one and task 2 to finish so there is a
something called weight all so you can
do weigh all or weight any and then we
can say task 1 task to wait for all of
them to finish and then we can get a
waiter a waiter one because task 1 got a
waiter and a waiter to the coach task to
get a waiter and from my waiter we can
get the result so we're gonna get a
result result 1 equals waiter 1 the
result and result two eCos a waiter to
get result so in this case we are able
to get the result from one or two from
calculate one and calculate two and then
we can feed it to calculate three
calculate three ways result one the
result
- okay let's front-end see this time the
sequence is different again because
because calculate one runs first but it
takes longer for it to finish so that's
why I calculate to print to the screen
first
Cokely to print to the screen first and
then calculate one and because calculate
three weights to both of the to finish
that's why I calculate three appears on
the screen on the third place alright so
let's take let's see a different
scenario where maybe calculate two
depends on calculate one right
so calculate two depends on calculate
one in that case we want to change this
to result one and then they want to do
result one times two we return this and
so that's this makes result two relies
on result one by result three does not
rely on result one so so what we need to
do in this case
is that we need to maybe we can use this
wanna got the waiter one right we got a
waiter one and then we can say a waiter
dot uncompleted okay so we were waiting
for the task one to complete and then
inside here we can get results from my
waiter one we can get so here
a waiter one when a waiter one completes
which means when the task first first
task complete
then we use a waiter one to get the
result this is the result from calculate
one which is an integer and then we can
call calculate two and feed the result
one to calculate two and after that
we'll call calculate three we can make
calculate three has no relationship with
chocolate to test us not depend it does
not depend on calculate one or coke
later here we just return 300 all right
in this case we look at again task one
runs but then when it finishes it costs
this so this is so-called callback
function this is a callback callback
function so them their expression it's a
delegate and this is the function this
here is the function and what it does is
that it gets the result from task one
and then cause chocolate chocolate - and
this is a async there's call so
calculates three will
actually we'll run first because it
takes a long time takes three seconds to
for task 1 to finish so what we'll see
is that it was a calculating resolved 3
and then it will print calculating
result 1 and call anything result - so
let's see whether it does that or not so
calculating grizzle 3 that comes first
and then 1 and 2 so so this is this is
the async async there's programming
functionality in c-sharp there's a lot
of different other things but this is
the basic of the of the asynchronous
programming in C sharp and it's using a
sort of callback and if we want to wait
for something we can use we can use
tasks to wait who either wait anyway oh
so there's another thing that we now
they see a lot of function test that
says async at the first and then inside
it says await
so what is about those what is about the
the async and the way it keywords it
looks sort of confusing because looks
like it's not a asynchronous programming
it looks like a sink neurs like
everything is as being called
synchronously and that's actually the
point the point is that to simplify the
async there's programming so that it has
a feel of sink there's programming but
but it's a table Osiris sword it's it's
it is actually indeed confusing so so
this this way we do it this way they're
actually pretty clear that this is a
this is a callback function and this
runs first I mean this this these will
run first but then it will go through
and then this one this will actually
goes through really quickly and then we
run this one and then when when all of
that finishes because in
this structure is pretty clear but but
but it's probably nicer if we can we can
make it look like a sink nearest
programming so let's see let's see how
we I say in this same case that
calculate - depends on calculate one and
calculates three does not in this case
what do we do alright so what do we do
how do we how do we use a sink and a way
to implement the same thing so so for
that we want to create a new a new
function I'll call it task I'll
calculate one and two and inside here we
are going to have we're gonna call this
copy this over here right and we are
going to await this and when we are
awaited we will actually get a result
from here right and this result is an
integer and here we are because we're
waiting for that for calculate want to
finish then at this line we will get the
result
already all right we'll get it so that
we can call calculate two feet add to it
so in this case
we can call okay one two yep this
supposed to be static so we're calling
this function and because we are not
awaiting it we're not waiting it to
finish so as soon as this executes well
this calculate 3 will be executed right
and then let's run it and let's see how
it works so it does the calculation 3
first and then first and then does the
calculating one and calculating two and
let's see how it works so this function
gets called first and what happens here
is that it runs calculate 1 and actually
it will actually return from here and
then directly calculates this and after
does calculate 1 finishes it will come
back and execute calculate 2
hopefully that's clear so so so again
calculates fun calculate is called and
calculate 1 2 function which is this
function is called when this function is
called this task gets executed but
because we have a weight keyword here
this async and the way to mix this
calculate one and a score to function a
asynchronous function so will actually
return right away
kind of like finishes but kind of like a
pauses right away
then if I can execute the next lines and
next line the next line as soon as the
stocks finishes I will continue from
here
I remember a past so it will continue
from where it paused so continue from
here that's why we saw calculating 3
first and then calculating one and then
calculating - it didn't show calculating
- right it showed calculating one before
showing calculating - so calculating -
is actually waiting for calculating one
to finish but calculating three runs
first because this is a Sinclairs
function what if we add a what if we add
a here they think and then we and we
make this return a task and we await we
await this one a way to calculate one
and two and then we call it we also we
can await this one so yeah so what if we
create another static method and call it
test from here we make this one an async
and we await a way to calculate or we
calculate
well we have to or we got a task here
and we do this what will happen guess
what will happen I'm gonna put a test
here of course so the task will be
called and then it will await this to
finish and when this is called
will await 1 & 2 to finish alright so
cut calculus 3 will not be called it's
that cochlear one and will be called and
when one finishes so actually pauses
here right but but then when it finishes
calls calculate 2 and when calculate 1 &
2 finishes the cost chemistry so when we
run in or see that calculate 1 prints
first and then 2 & 3 so apart by the
normal sequence see 1 2 & 3
yeah I think that's all I want to talk
about today about anything there's
programming and I hope that is helpful
if you liked it please give it a thumb
thumb up and subscribe as well thank you
so much
Посмотреть больше похожих видео
C# Async/Await/Task Explained (Deep Dive)
Asynchrony: Under the Hood - Shelley Vohr - JSConf EU
How to use escaping closures in Swift | Continued Learning #20
Asynchronous JavaScript in ~10 Minutes - Callbacks, Promises, and Async/Await
Node.js Tutorial - 42 - Event Loop
Javascript Promises vs Async Await EXPLAINED (in 5 minutes)
5.0 / 5 (0 votes)