C
C#3mo ago
Shinigami

Why does Task 1 prints first instead of Task 3 - Async & Await

internal class Program
{
private static async Task Main(string[] args)
{
Task firstTask = Task.Run(async ()=> {
// Thread.Sleep(1000);
await Task.Delay(10000);
Console.WriteLine("Task 1");
});
// firstTask.Start();
// Console.WriteLine("YOYOYOY");
await firstTask;

Task secondTask = ConsoleWithDelayAsync("Task 2",150);
Task thirdTask = ConsoleWithDelayAsync("Task 3",9);
Task fourthTask = ConsoleWithDelayAsync("Task 4",80);

await secondTask;
await thirdTask;
await fourthTask;
}

public static void ConsoleWithDelay(string text, int delay){
Thread.Sleep(delay);
Console.WriteLine(text);
}

public static async Task ConsoleWithDelayAsync(string text, int delay){
await Task.Delay(delay);
Console.WriteLine(text);
}
}
internal class Program
{
private static async Task Main(string[] args)
{
Task firstTask = Task.Run(async ()=> {
// Thread.Sleep(1000);
await Task.Delay(10000);
Console.WriteLine("Task 1");
});
// firstTask.Start();
// Console.WriteLine("YOYOYOY");
await firstTask;

Task secondTask = ConsoleWithDelayAsync("Task 2",150);
Task thirdTask = ConsoleWithDelayAsync("Task 3",9);
Task fourthTask = ConsoleWithDelayAsync("Task 4",80);

await secondTask;
await thirdTask;
await fourthTask;
}

public static void ConsoleWithDelay(string text, int delay){
Thread.Sleep(delay);
Console.WriteLine(text);
}

public static async Task ConsoleWithDelayAsync(string text, int delay){
await Task.Delay(delay);
Console.WriteLine(text);
}
}
The output I'm getting is Task 1 Task 3 Task 4 Task 2 Aren't all the Tasks async above? So while Task 1 waits for 10 secs should the rest of the code continue?
33 Replies
AntiHeroKid
AntiHeroKid3mo ago
But aren't all of your tasks inside firstTask?
Shinigami
ShinigamiOP3mo ago
No, all are separate different tasks
Kouhai
Kouhai3mo ago
You can think of await as currently stop "here" until the task finishes So what's happening is that you're starting firstTask firstTask internally awaits for 10 seconds In your Main method you're awaiting for firstTask to complete, this means Main will wait for 10seconds as well After firstTask is completed, Main can continue executing Which means starting 3 tasks secondTask, thirdTask and fourthTask
AntiHeroKid
AntiHeroKid3mo ago
oh sorry...yeah so....You see. They are asyncronous yes but using await makes them run sequentially.
Kouhai
Kouhai3mo ago
No await doesn't mean the tasks are ran sequentially For example
await secondTask;
await thirdTask;
await fourthTask;
await secondTask;
await thirdTask;
await fourthTask;
Doesn't mean secondTask will finish before third or foruth task
Shinigami
ShinigamiOP3mo ago
maybe I'm getting this wrong or something, buttt wouldn't the whole purpose of async is to not stop the code?
Kouhai
Kouhai3mo ago
We'll it's more complicated than that Just to be sure, do you have an JS background?
Shinigami
ShinigamiOP3mo ago
Also if you await the firstTask after creating 2,3,4 tasks then firstTask output is last
Kouhai
Kouhai3mo ago
Yes
AntiHeroKid
AntiHeroKid3mo ago
Sorry you are correct. It just pauses the main thread.
Shinigami
ShinigamiOP3mo ago
I do, i know about promise and stuff but, async await isn't clear so i keep coming back to it.
AntiHeroKid
AntiHeroKid3mo ago
@Shinigami Just remember what kouhai said
You can think of await as currently stop "here" until the task finishes
Shinigami
ShinigamiOP3mo ago
Why tho? What's the difference awaiting before the 2,3,4 tasks are created and after the tasks are created? Okay.. but a normal synchronous function does the same too right? Waits untill the function completes... I'm missing the nuance here i guess
AntiHeroKid
AntiHeroKid3mo ago
focus on await
Kouhai
Kouhai3mo ago
Okay so You can think of a Task as some sort of a "promise" a promise that something will be completed sometime in the future (it may succeed or fail) So when we have this
Task<string> result = ReallySlowNetworkRequest();
Task<string> result = ReallySlowNetworkRequest();
result is just that promise, when we do await result we want to suspend the evaluation "here" (here meaning the place where we await) When we suspend the evaluation, we can't continue execute the code in the same method under it until result either succeeds or fails
AntiHeroKid
AntiHeroKid3mo ago
if you don't use await the tasks have already began executing concurrently. The moment you created them
Kouhai
Kouhai3mo ago
When you await before 2,3,4 are created, you're suspending execution, so 2,3,4 haven't been created or started yet
AntiHeroKid
AntiHeroKid3mo ago
Task secondTask = ConsoleWithDelayAsync("Task 2",150); Task thirdTask = ConsoleWithDelayAsync("Task 3",9); Task fourthTask = ConsoleWithDelayAsync("Task 4",80);
They have began running concurrently. but the await firstTask before them is like, as Kouhai said. Please wait for the firstTask to complete before moving forward.
Kouhai
Kouhai3mo ago
imagine that you have 4 coffee machines You start one of them on a program that takes 2 minutes and you wait for it to finish After it finishes, you put coffee in the three other machines and wait for the three other machines to finish
AntiHeroKid
AntiHeroKid3mo ago
i used to be confused about this as well. But the thing is await here is helping us to run the code sequentially in the sense that it is going to wait for secondTask to complete (even though thirdTask and fourthTask may have compeleted already) as Kouhai pointed out my mistake. @Shinigami do you understand better now?
Shinigami
ShinigamiOP3mo ago
I kinda do and i kinda don't.. the first task suspends for 10sec, i got it.. but what about the 2nd, 3rd and 4th task? When I'm awaiting those 3 tasks why don't I receive output sequentially?
Kouhai
Kouhai3mo ago
When you start three coffee machines Will they finish sequentially or will they finish depending on how long each program is?
Shinigami
ShinigamiOP3mo ago
Yeah this doesn't happen sequentially
AntiHeroKid
AntiHeroKid3mo ago
Bruh as @Kouhai pointed out my mistake, they won't be sequential. They run asynchronously only.
Shinigami
ShinigamiOP3mo ago
So in essence it all depends on when i await, right?
AntiHeroKid
AntiHeroKid3mo ago
All we are saying wait for Task 2 to complete before moving forward in the code. Task 3 and Task 4 may have already be finished.
Kouhai
Kouhai3mo ago
Bingo, even if you're waiting for Machine B to finish, as long as all machines have already started they won't be sequential
AntiHeroKid
AntiHeroKid3mo ago
when we await Task 1 we didn't even create rest of the tasks. So they were not even in the picture. if they were moved before await Task 1, then yes they would run before i am 100 % sure. hugs kouhai
Shinigami
ShinigamiOP3mo ago
Okayyyy! I kinda get it. So, in the beginning all I have is 1st task and that will wait for x secs. So it WILL wait for 10 secs if i create other tasks AFTER the await. But if i create all tasks and await all tasks at the same time then it will depend on which tasks finishes first...
Kouhai
Kouhai3mo ago
Yes, exactly
Shinigami
ShinigamiOP3mo ago
So I thought since it's async, if i await and then create other tasks the task would wait for 10 secs but the rest of the tasks (2,3,4) would get created and waited at the same time... that's not the case i guess
AntiHeroKid
AntiHeroKid3mo ago
you still need to make control flow decisions, and make sure the program runs predictably. That's where await is helpful. like task 1 is download images task 2 is download videos task 3 is upload whatever data you currently downloaded you would want task 3 i.e. uploading to happen once task 1 and task 2 are completed.
Shinigami
ShinigamiOP3mo ago
Yes sir, thanks you both. I understood it.
Want results from more Discord servers?
Add your server