In C#,
static async Task<int> Task1()
{
await Task.Delay(1000); // delaying 1 sec
return 10;
}
static async Task<int> Task2()
{
await Task.Delay(2000); // delaying 2 sec
return 10;
}
static async Task<int> Task3()
{
await Task.Delay(3000); // delaying 3 sec
return 10;
}
when performing below operations it takes 6 sec
int a = await Task1();
int b = await Task2();
int c = await Task3();
return a b c;
but when performing below operations it takes only 3 sec
var a = Task1();
var b = Task2();
var c = Task3();
return await a await b await c;
results are getting as 30 from both the snippet but duration differs...
Can anyone please clarify it
reference - https://dotnetfiddle.net/I31eqK
CodePudding user response:
When you do this:
int a = await Task1();
int b = await Task2();
int c = await Task3();
return a b c;
each task is awaited before the next one is started. That is, each task must have returned a result before the next task is awaited. Thus, the total time is the total time for all tasks.
But when you do this:
var a = Task1();
var b = Task2();
var c = Task3();
return await a await b await c;
the three tasks are started in parallel, and THEN you await their results. Thus in this case the total time is whatever the longest task takes.
CodePudding user response:
With
var a = Task1(); // Started here
var b = Task2(); // Started here
var c = Task3(); // Started here
var r = await a await b await c;
the tasks are started pretty much at the same time.
With:
int a = await Task1();
int b = await Task2();
int c = await Task3();
return a b c;
the 2nd task starts only when the first one finishes.
The following code would take ~6 seconds:
Func<Task<int>> a = async () => await Task1(); // Not started here
var b = async () => await Task2(); // Not started here
var c = async () => await Task3(); // Not started here
var r = await a() await b() await c();
Console.WriteLine(r);
CodePudding user response:
When you do the following:
int a = await Task1();
int b = await Task2();
int c = await Task3();
You are awaiting the task to complete, in other words, once execution of Task1 starts, it will not execute Task2 untill Task1 completes. You are awaiting the Task to complete.
When you do:
var a = Task1();
var b = Task2();
var c = Task3();
You are not awaiting for each individual task to complete, instead, you are executing the Tasks, and the thread pool manages these tasks, and in some cases, can run them simultaniously, resulting in faster times. For example, if Task1, Task2, Task3 are run in parralel, best case scenario, is that it will take 3 seconds to complete.
CodePudding user response:
The code below works synchronously. Meaning that you are queuing up the tasks in series (therefore executing them one-by-one) as the functions wait patiently for the ones above them to finish like gentlemen.
Figuratively: "waiting for one to finish their sentence before speaking".
int a = await Task1(); // wait for the above function/Task to complete THEN run this one ("wait for one to finish their sentence THEN talk")
int b = await Task2(); // wait for the above function/Task to complete THEN run this one ("wait for one to finish their sentence THEN talk")
int c = await Task3(); // wait for the above function/Task to complete THEN run this one ("wait for one to finish their sentence THEN talk")
return a b c; // return the values received
In the code below, Instead of waiting the function to finish and return one-by-one, you are instead ("asynchronously") waiting for all of the included variables to have a value (as you are not waiting for one function to finish before running the next one, but rather waiting for every necessary value to exist).
Figuratively: "Talking over each other, therefore ending the conversation earlier than waiting for one to finish their sentence".
var a = Task1(); // Run this function while other functions are running ("Talk while other people are talking")
var b = Task2(); // Run this function while other functions are running ("Talk while other people are talking")
var c = Task3(); // Run this function while other functions are running ("Talk while other people are talking")
return await a await b await c; // now wait for every variable to have their own value and THEN return
Examples
Here's an example to make this easy to understand:
int a = Task1(); // Asynchronous call ("Dont wait for someone to finish speaking")
int b = Task2(); // Asynchronous call ("Dont wait for someone to finish speaking")
int c = await Task3(); // Synchronous call ("wait for someone/people to finish talking)
The code above should take 5 seconds because:
Task1()
pauses for 1000 milliseconds and runs at the same time as Task2()
with its 2000 milliseconds (as Task1 and Task2 are not waiting for each other to finish), As Task1 Finishes in 1 second where as Task2 will finish in 2 Seconds, therefore taking it 2 seconds before Task3 is called
Task3()
, with its 3000 millisecond pause, will wait patiently until all functions before it are done with their own thing. Because Task2 is finished, Task3 is then called, adding an additional 3 seconds to the 2 seconds Total.
Extra Note: Please run this script (not on dotnetfiddle.com as it doesn't show the live output but rather on your local machine): https://www.toptal.com/developers/hastebin/igapunubis.csharp