Shows two flows: one reads data synchronously from a stream, the other reads asynchronously using async streams with await.
Execution Sample
C Sharp (C#)
var numbers = newList<int> {1, 2, 3};
// Sync stream
foreach(var n in numbers) {
Console.WriteLine(n);
}
// Async stream
async IAsyncEnumerable<int> GetNumbersAsync() {
foreach(var n in numbers) {
await Task.Delay(10);
yield return n;
}
}
This code shows a synchronous foreach loop over a list and an asynchronous stream that yields numbers with a delay.
Execution Table
Step
Operation
Awaited?
Value Produced
Output
1
Start synchronous foreach
No
None
None
2
Read first number (1)
No
1
Print 1
3
Read second number (2)
No
2
Print 2
4
Read third number (3)
No
3
Print 3
5
End synchronous foreach
No
None
None
6
Call GetNumbersAsync()
No
None
None
7
Await Task.Delay(10) before yield 1
Yes
None
None
8
Yield return 1
No
1
Print 1
9
Await Task.Delay(10) before yield 2
Yes
None
None
10
Yield return 2
No
2
Print 2
11
Await Task.Delay(10) before yield 3
Yes
None
None
12
Yield return 3
No
3
Print 3
13
End async stream
No
None
None
💡 Synchronous loop ends after all items are read; async stream ends after all awaited yields complete.
Variable Tracker
Variable
Start
After Step 2
After Step 3
After Step 4
After Step 8
After Step 10
After Step 12
Final
n
undefined
1
2
3
1
2
3
3
numbers Enumerator Position
Before start
At 1
At 2
At 3
At 1
At 2
At 3
End
Key Moments - 3 Insights
Why does the async stream use 'await' before yielding values?
Because the async stream simulates asynchronous work (like waiting for data), it uses 'await Task.Delay' to pause before yielding each value, as shown in steps 7, 9, and 11 in the execution_table.
Does the synchronous foreach wait or pause during iteration?
No, the synchronous foreach reads and processes each item immediately without waiting, as seen in steps 2, 3, and 4 where values are printed right away.
What happens if you forget to 'await' the async stream?
You won't get the values properly because the async stream requires awaiting each yield to handle asynchronous delays, shown by the awaited steps in the execution_table (7, 9, 11). Without await, the program won't pause and process data correctly.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, at which step does the async stream first yield a value?
AStep 8
BStep 7
CStep 9
DStep 10
💡 Hint
Check the 'Value Produced' column for the first yield in the async stream section.
According to variable_tracker, what is the value of 'n' after step 4?
A1
B3
C2
Dundefined
💡 Hint
Look at the 'n' row and the column for 'After Step 4' in variable_tracker.
If the 'await Task.Delay(10)' was removed from the async stream, how would the execution_table change?
AThe async stream would yield values immediately without delay
BThe synchronous stream would wait longer
CSteps with 'Awaited?' marked 'Yes' would be gone
DThe program would crash
💡 Hint
Check which steps have 'Awaited?' as 'Yes' and consider what removing await means.
Concept Snapshot
Synchronous streams read data immediately in a loop.
Async streams use 'await' to pause and yield data asynchronously.
Use 'foreach' for sync streams and 'await foreach' for async streams.
Async streams allow non-blocking data processing.
Remember to await async streams to get values correctly.
Full Transcript
This visual execution compares synchronous and asynchronous streams in C#. The synchronous stream reads and prints each number immediately in steps 2 to 4. The async stream uses 'await Task.Delay' to simulate waiting before yielding each number in steps 7, 9, and 11. Variables like 'n' track the current value being processed. Key moments clarify why async streams await before yielding and how synchronous streams differ by processing immediately. The quizzes test understanding of when values are yielded and the effect of removing awaits. The snapshot summarizes the main differences and usage rules for sync and async streams.
Practice
(1/5)
1. What is the main difference between a Stream and an async stream in C#?
easy
A. A Stream processes data synchronously, while an async stream processes data asynchronously.
B. A Stream can only read data, but an async stream can only write data.
C. A Stream is used for text data, and an async stream is used for binary data.
D. There is no difference; both work the same way.
Solution
Step 1: Understand Stream behavior
A Stream reads or writes data step-by-step synchronously, blocking the thread until data is processed.
Step 2: Understand async stream behavior
An async stream uses IAsyncEnumerable<T> and await foreach to process data asynchronously, allowing other work while waiting for data.
Final Answer:
A Stream processes data synchronously, while an async stream processes data asynchronously. -> Option A
Quick Check:
Sync vs async processing = C [OK]
Hint: Sync streams block; async streams use await foreach [OK]
Common Mistakes:
Thinking async streams are only for writing data
Confusing synchronous with asynchronous processing
Believing streams only handle text or binary exclusively
2. Which of the following is the correct syntax to consume an async stream in C#?
easy
A. foreach (var item in asyncStream) { Console.WriteLine(item); }
B. await foreach (var item in asyncStream) { Console.WriteLine(item); }
C. for await (var item in asyncStream) { Console.WriteLine(item); }
D. async foreach (var item in asyncStream) { Console.WriteLine(item); }
Solution
Step 1: Recall async stream consumption syntax
Async streams require await foreach to asynchronously iterate over IAsyncEnumerable<T>.
Step 2: Check each option
foreach (var item in asyncStream) { Console.WriteLine(item); } uses regular foreach which is invalid for async streams. await foreach (var item in asyncStream) { Console.WriteLine(item); } correctly uses await foreach. for await (var item in asyncStream) { Console.WriteLine(item); } uses invalid syntax for await. async foreach (var item in asyncStream) { Console.WriteLine(item); } uses invalid keyword order async foreach.
Final Answer:
await foreach (var item in asyncStream) { Console.WriteLine(item); } -> Option B
Quick Check:
Async stream needs await foreach = A [OK]
Hint: Use 'await foreach' to read async streams correctly [OK]
Common Mistakes:
Using regular foreach with async streams
Swapping 'async' and 'await' keywords incorrectly
Trying 'for await' which is invalid in C#
3. Consider this code snippet:
async IAsyncEnumerable<int> GetNumbersAsync()
{
for (int i = 1; i <= 3; i++)
{
await Task.Delay(100);
yield return i;
}
}
static async Task Main()
{
await foreach (var num in GetNumbersAsync())
{
Console.Write(num + " ");
}
}
What will be the output when this program runs?
medium
A. Task not awaited error
B. 123
C. 1 2 3
D. No output
Solution
Step 1: Understand async stream generation
The method yields numbers 1 to 3 with a 100ms delay between each, simulating asynchronous data arrival.
Step 2: Understand async stream consumption
The await foreach prints each number followed by a space as they arrive asynchronously.
Final Answer:
1 2 3 -> Option C
Quick Check:
Async yield with await foreach prints spaced numbers = A [OK]