Let's dive deeper into the behavior of async/await and how it changes the program's flow in two scenarios:
When we don't use 'await', tasks are started but not awaited, allowing the program to continue immediately.
When we use 'await', the program pauses and waits for the task to finish before proceeding.
I have Order Pizza and Order Drink like this:
class Program
{
public static async Task OrderPizza()
{
Console.WriteLine("Ordering Pizza...");
await Task.Delay(1000); // Simulate 1 seconds of work
Console.WriteLine("Pizza ready!");
}
public static async Task OrderDrink()
{
Console.WriteLine("Ordering Drink...");
await Task.Delay(2000); // Simulate 2 seconds of work
Console.WriteLine("Drink ready!");
}
}
Understanding the two Code Snippets.
Here are the two scenarios you're asking about:
1. Without await:
public static async Task Main(string[] args)
{
OrderPizza();
Console.WriteLine("This is synchronous script");
OrderDrink();
}
2. With await:
public static async Task Main(string[] args)
{
await OrderPizza(); // Waits for pizza to completenchat
Console.WriteLine("This is synchronous script");
await OrderDrink(); // Waits for drink to complete
}
Okie let's start with:
How they Work Internally
1. Without await:
(Note: The use of MainThread for simplification is understandable, but clarifying how the ThreadPool handles tasks would make it more precise).
Code Behavior:
- OrderPizza() is called, but it does not blocked the main thread. It starts running in the background if it is asynchronous.
- The program immediately executes Console.WriteLine("This is synchronous script")
- Then, it calls OrderDink() without waiting for OrderPizza() to finish
Result:
- The "This is synchronous script" message appears before the pizza or drink task complete.
- Task for OrderPizza and OrderDrink run in parallel (overallap);
Output Example (Non-deterministic due to overlapping):
Ordering Pizza...
Successfully
Ordering Drink... --> actual print in the terminal when the program completed
Drink ready!
Pizza ready! -->Do not show in terminal b/c it runs and completes in the Background task
2. With Await
Code Behavior:
- await OrderPizza is called, and the program waits until the OrderPizza task finishes
- After OrderPizza completes, Console.WriteLine("This is synchronous script") is executed.
- Then, await OrderDrink is called, and the program waits again for OrderDrink to finish.
Result:
- Tasks run sequentially.
- The pizza must finish before moving to the "This is synchronous script" message, and the drink must finish before proceeding further. (The program must wait for each task to complete before moving to the next step)
Ordering Pizza...
Pizza ready!
This is synchronous script
Ordering Drink...
Drink ready!
Summary: Key Differences Between the Two
Aspect | Without await | With await |
---|---|---|
Execution Order | Non-sequential, overlaps tasks. | Sequential, tasks execute in order. |
Message Timing | next script run immediately. | Next script waits for completion. |
Use Case | Use when task order doesn’t matter. | Use when task order matters. |
Thread Blocking | Non-blocking but lacks control. | Non-blocking with full control. |
When to Use Each?
Without await:
Use this approach when tasks can run independently, and you don’t care about the order or timing of their completion. For example, sending analytics data to a server while continuing with other work.
With await:
Use this approach when the task order matters, or the next step depends on the completion of the previous task. For example, processing a user’s order where pizza preparation must finish before delivering the drink.
Top comments (0)