Consider the following code:
public static void Run() {
DoStuffAsync();
}
public static async Task DoStuffAsync() {
PerformCalc();
await DoLongTaskAsync();
PerformAnotherCalc();
}
Let's say I call Run()
. I have a few questions regarding behaviour:
PerformCalc()
be called synchronously on the same thread as the one that called Run()
?DoLongTaskAsync()
be called asynchronously or synchronously? In other words, will/can PerformAnotherCalc()
be called before DoLongTaskAsync()
has finished?DoStuffAsync()
method return before execution of DoLongAsyncTask()
has completed?The call to the async method starts an asynchronous task. However, because no Await operator is applied, the program continues without waiting for the task to complete. In most cases, that behavior isn't expected.
You can use the await keyword on its own (outside of an async function) within a JavaScript module. This means modules, with child modules that use await , wait for the child module to execute before they themselves run.
In computer programming, the async/await pattern is a syntactic feature of many programming languages that allows an asynchronous, non-blocking function to be structured in a way similar to an ordinary synchronous function.
Async function without await insideWe can declare a function as async without using any await . In this case, the execution is not paused and your code will be executed in a non-blocking manner (asynchronous - no waiting). It is the same as not declaring that same function with async .
Async methods always start running synchronously. The magic happens at await
, but only when await
is given a Task
that has not completed.
In your example, this is what will happen when you call Run()
:
DoStuffAsync()
PerformCalc()
DoLongTaskAsync()
DoLongTaskAsync()
is a truly asynchronous operation and returns an incomplete Task
, then await
does its job and DoStuffAsync()
returns an incomplete Task
to Run()
.Run()
completes.DoLongTaskAsync()
completes, DoStuffAsync()
resumes, and jumps to PerformAnotherCalc()
.All of that can happen on the same thread.
So to answer your questions:
async
method, it might end up going out and doing things on other threads. But it will start synchronously on the same thread.DoLongTaskAsync()
will be called asynchronously, but PerformAnotherCalc()
will not be called before DoLongTaskAsync()
finishes, because you used await
.await
works. It will return an incomplete Task
(that is, only if DoLongTaskAsync()
is truly asynchronous and returns an incomplete Task
). Then once DoLongTaskAsync()
finishes, execution of DoStuffAsync()
resumes where it left off.
- Will PerformCalc() be called synchronously on the same thread as the one that called Run()?
Yes.
- Will DoLongTaskAsync() be called asynchronously or synchronously? In other words, will PerformAnotherCalc() be called before DoLongTaskAsync() has finished?
It will be called synchronously, but it may return a Task
before the "Long Task" operation has finished. Either way, the Task
it returns is awaited, so PerformAnotherCalc
will not be called until the Task
returned from DoLongTaskAsync
completes.
- Subsequently, can the DoStuffAsync() method return before execution of DoLongAsyncTask() has completed?
The DoStuffAsync
method will return when it hits the first await
(iff the Task
being awaited is pending). That's how async
methods work -- they run synchronously up until the first await
of a Task
which is pending, and then they return a Task
which will complete when the whole method has executed.
If might be that DoLongTaskAsync
returns a Task
which has already completed: in that case, DoStuffAsync
won't return until PerformAnotherCalc
has returned. If DoLongTaskAsync
returns a Task
which is still pending, then DoStuffAsync
will return at that point, and it will return a Task
which completes once the Task
returned from DoLongTaskAsync
has completed, and PerformAnotherCalc
has returned.
Put otherwise, if you consider those methods:
public static void Run1() {
DoStuffAsync();
Console.WriteLine("Done");
}
public static async Task Run2() {
await DoStuffAsync();
Console.WriteLine("Done");
}
public static async Task DoStuffAsync() {
PerformCalc();
await DoLongTaskAsync();
PerformAnotherCalc();
}
In Run2
, you are guaranteed that "Done" will be displayed after PerformAnotherCalc
. In Run1
, "Done" will be displayed after PerformCalc
but before PerformAnotherCalc
(assuming that DoLongTaskAsync
is actually asynchronous, which depends of its implementation).
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