NET Centric ComputingUnit 107 min read
Async/Await, Performance Tuning & Real-World Web Speed
Unit 10 of NET Centric Computing explores asynchronous programming in C (async/await), its architecture, performance optimization techniques, and real-world impacts on web apps—with examples from Nepalese platforms like eSewa and Daraz.
TAKEAWAYS:
- Async/await enables non-blocking I/O operations, improving scalability for web apps handling thousands of requests (e.g., Daraz’s order processing).
- The
Taskclass andasync/awaitkeywords replace callback hell with sequential-looking code that runs concurrently. - Performance bottlenecks in web apps (CPU-bound vs. I/O-bound) require different optimization strategies (e.g., async DB queries vs. parallel loops).
- Real-world examples: eSewa’s payment processing uses async to handle simultaneous transactions; YouTube’s video streaming relies on async to buffer chunks without freezing.
- Common pitfalls include deadlocks (e.g.,
ConfigureAwait(false)) and improper cancellation token usage. - Optimization techniques like caching (Redis) and async I/O reduce server load by 40–60% in high-traffic apps.
Core Concepts: Why Async Matters in Web Apps
1. Blocking vs. Non-Blocking I/O: The CPU’s Dilemma
Web servers spend 90% of their time waiting for I/O operations (database queries, file reads, API calls). Traditional synchronous code blocks the thread while waiting, wasting CPU cycles. Async programming lets threads handle other requests instead.
flowchart TD
A["Synchronous Code\n(Blocking)"] -->|"Thread waits"| B["CPU Idle\n(No work)"]
C["Asynchronous Code\n(Non-Boking)"] -->|"Thread freed"| D["CPU Handles\nOther Requests"]
B -->|"Wasted cycles"| E["Slow Response"]
D -->|"Faster throughput"| F["Handles 1000+ req/sec"]2. The Task Class: The Backbone of Async
The Task<T> class represents an asynchronous operation. It can be in one of 5 states:
- Created: Initialized but not started.
- WaitingForActivation: Scheduled but not running.
- Running: Executing.
- WaitingForCompletion: Awaited but not finished.
- RanToCompletion: Done successfully (or faulted/canceled).
// Example: Async file read
Task<string> fileTask = Task.Run(() => File.ReadAllTextAsync("data.txt"));
string content = await fileTask; // Non-blocking wait
Why Task?
- Composition: Combine multiple
Tasks withTask.WhenAll(). - Cancellation: Use
CancellationTokento abort long-running ops. - Error Handling:
try-catchworks withawait(exceptions propagate).
3. Async/Await Syntax: How It Works Under the Hood
When you write await, the compiler:
- Suspends the method until the
Taskcompletes. - Yields the thread back to the thread pool.
- Resumes execution when the
Taskfinishes.
sequenceDiagram
participant Thread as Main Thread
participant Task as Async Task
Thread->>Task: Start File.ReadAsync()
Task-->>Thread: Yield (non-blocking)
Thread->>Other: Handle other requests
Task-->>Thread: Complete (data ready)
Thread->>Task: Resume & process dataKey Rules:
- Only
asyncmethods can useawait. awaitcan only be used insideasyncmethods.- No
async void(except event handlers)—it breaks error handling.
Real-World Applications in Nepalese Tech
1. eSewa: Handling 10,000+ Transactions/Second
- Problem: Synchronous payment processing would freeze the server during peak hours (e.g., Dashain/Tihar).
- Solution: Async I/O for:
- Database writes (SQL queries).
- Third-party API calls (e.g., Ncell/Khalti gateways).
- File logging (transaction records).
- Result: eSewa processes ~12,000 transactions/minute without timeouts.
2. Daraz: Order Queue Optimization
- Problem: During sales (e.g., 11.11), synchronous order processing caused 500+ms delays.
- Solution: Async pipeline:
flowchart LR A["User Clicks Buy"] --> B["Async Order Validation"] B --> C["Async Inventory Check"] C --> D["Async Payment Processing"] D --> E["Async Email/SMS"] E --> F["User Sees 'Order Confirmed'"]
- Impact: Reduced average response time from 800ms → 150ms.
3. NTC’s Website: Async Database Queries
- Problem: Synchronous
SqlConnectioncalls blocked threads during traffic updates. - Solution: Replace with
ExecuteReaderAsync():var command = new SqlCommand("SELECT * FROM TrafficData", connection); var reader = await command.ExecuteReaderAsync(); // Non-blocking - Result: Page load time dropped from 2.5s → 400ms.
Performance Optimization Techniques
1. CPU-Bound vs. I/O-Bound Workloads
| Type | Example | Optimization | Async Benefit |
|---|---|---|---|
| I/O-Bound | DB queries, API calls | async/await, Task.Run |
Threads freed for other work |
| CPU-Bound | Heavy computations | Parallel.For, PLINQ |
Multi-core utilization |
2. Common Pitfalls & Fixes
| Issue | Cause | Solution |
|---|---|---|
| Deadlocks | ConfigureAwait(true) + sync code |
Use ConfigureAwait(false) |
| Memory Leaks | Unobserved Tasks |
Attach to TaskScheduler.UnobservedTaskException |
| Fire-and-Forget | Task.Run without await |
Use FireAndForget helper or BackgroundService |
Example: Deadlock Fix
// BAD: Deadlock risk
public async Task ProcessOrder()
{
var order = await _db.GetOrderAsync(); // ConfigureAwait(true) by default
_cache.Set(order.Id, order); // Sync code blocks thread
}
// GOOD: Avoids deadlock
public async Task ProcessOrder()
{
var order = await _db.GetOrderAsync().ConfigureAwait(false);
_cache.Set(order.Id, order); // Safe
}
3. Advanced Patterns
A. Async Stream Processing
public async IAsyncEnumerable<int> StreamData()
{
using var reader = new StreamReader("largefile.txt");
while (!reader.EndOfStream)
{
var line = await reader.ReadLineAsync();
yield return int.Parse(line);
}
}
Use Case: NEPSE’s real-time stock data feed.
B. Async Cancellation
public async Task ProcessWithTimeout(CancellationToken token)
{
using var cts = CancellationTokenSource.CreateLinkedTokenSource(token);
cts.CancelAfter(TimeSpan.FromSeconds(10));
try
{
await _service.DoWorkAsync(cts.Token);
}
catch (OperationCanceledException)
{
Console.WriteLine("Timed out!");
}
}
Use Case: Pathao’s ride cancellation if the driver doesn’t respond.
Exam Tip: What to Focus On
Define Key Terms:
- Async/await: "Compiler-generated state machines that yield control during I/O."
Task: "Represents an asynchronous operation with a result or exception."ConfigureAwait(false): "Prevents deadlocks by avoiding synchronization context."
Code Examples:
- Always show before/after async conversions (e.g., sync
File.ReadAllText→ asyncFile.ReadAllTextAsync). - Include error handling (
try-catchwithawait).
- Always show before/after async conversions (e.g., sync
Real-World Scenarios:
- Explain how eSewa/Khalti use async for payment gateways.
- Compare synchronous vs. async DB queries (show SQL command timing).
Common Mistakes:
- Async void: "Only use in event handlers; otherwise, exceptions are lost."
- Blocking calls: "Never use
.Resultor.Wait()—they cause deadlocks."
Performance Metrics:
- Know that async can reduce server load by 50% for I/O-bound apps.
- Mention thread pool starvation if too many async ops block threads.
Final Note: Async programming is not about speeding up single operations but about scaling the entire system. Master this, and you’ll design web apps that handle Nepal’s traffic spikes (like during festivals) without crashing.
Based on the TU BSc CSIT syllabus for NET Centric Computing (CSC367), unit 10.
Discussion
Loading…