Tutorial 3: Understanding Async/Await (In Plain English)
🎯 What You’ll Learn
- What
asyncandawaitmean - Why we use them
- How to use them correctly
- Common mistakes to avoid
📚 Prerequisites
🍳 The Restaurant Analogy
Imagine you’re at a restaurant. There are two ways to get your food:
Method 1: Stand and Wait (Synchronous)
1. You order a burger
2. You stand at the counter
3. You can't do anything else
4. You just wait... and wait...
5. Finally get your burger
6. Now you can do the next thing
Method 2: Take a Number (Asynchronous)
1. You order a burger
2. They give you a number
3. You sit down and chat with friends
4. You check your phone
5. They call your number
6. You get your burger
Async/Await is Method 2! Your program doesn’t freeze while waiting.
💻 In Code Terms
Without Async (Program Freezes)
// DON'T DO THIS - Your program will freeze!
public static void Main()
{
Console.WriteLine("Starting download...");
// This BLOCKS - program frozen here!
var result = DownloadWebpage("https://slow-website.com"); // Wait..... wait..... wait.....
Console.WriteLine("Finally done!"); // Only runs after download finishes
}
With Async (Program Stays Responsive)
public static async Task Main() // Note: async Task
{
Console.WriteLine("Starting download...");
// This DOESN'T BLOCK - program can do other things
var result = await DownloadWebpageAsync("https://slow-website.com");
Console.WriteLine("Done!"); // Runs after download, but program wasn't frozen
}
🔑 The Golden Rules
Rule 1: Async Methods End with “Async”
// Regular methods (avoid these for web requests)
Curl.Execute()
File.ReadAllText()
Download()
// Async methods (use these!)
Curl.ExecuteAsync()
File.ReadAllTextAsync()
DownloadAsync()
Rule 2: Always Use ‘await’ with Async Methods
// WRONG - Missing await
var result = Curl.ExecuteAsync("curl https://api.com");
// RIGHT - With await
var result = await Curl.ExecuteAsync("curl https://api.com");
Rule 3: Methods Using ‘await’ Must Be ‘async’
// WRONG - Method not marked as async
static Task<string> GetData()
{
var result = await Curl.ExecuteAsync("curl https://api.com"); // ERROR!
return result.Body;
}
// RIGHT - Method marked as async
static async Task<string> GetData()
{
var result = await Curl.ExecuteAsync("curl https://api.com"); // Works!
return result.Body;
}
🎯 Real Examples with CurlDotNet
Example 1: Simple Async Call
using System;
using System.Threading.Tasks;
using CurlDotNet;
class Program
{
static async Task Main() // async Task for Main
{
Console.WriteLine("Fetching data...");
// await tells C# to wait here (but not freeze)
var result = await Curl.ExecuteAsync("curl https://api.github.com");
Console.WriteLine($"Got {result.Body.Length} characters");
}
}
Example 2: Multiple Async Calls (One at a Time)
static async Task Main()
{
// These happen one after another
var result1 = await Curl.ExecuteAsync("curl https://api.github.com");
Console.WriteLine("Got first response");
var result2 = await Curl.ExecuteAsync("curl https://api.bitbucket.org");
Console.WriteLine("Got second response");
var result3 = await Curl.ExecuteAsync("curl https://api.gitlab.com");
Console.WriteLine("Got third response");
}
Example 3: Multiple Async Calls (All at Once!)
static async Task Main()
{
// Start all three at the same time!
var task1 = Curl.ExecuteAsync("curl https://api.github.com");
var task2 = Curl.ExecuteAsync("curl https://api.bitbucket.org");
var task3 = Curl.ExecuteAsync("curl https://api.gitlab.com");
// Wait for all to complete
var results = await Task.WhenAll(task1, task2, task3);
Console.WriteLine("Got all three responses at once!");
}
🤔 What’s Really Happening?
When you use await:
- Request Starts - The HTTP request begins
- Control Returns - Your program can do other things
- Request Completes - The server responds
- Code Resumes - Your code continues from the await line
It’s like ordering pizza:
- You call and order (start request)
- You watch TV while waiting (program does other things)
- Doorbell rings (request completes)
- You eat pizza (code continues)
⚡ Async vs Sync Comparison
Synchronous (Blocking)
// THIS FREEZES YOUR PROGRAM
public void DownloadFiles()
{
var file1 = DownloadFile("file1.zip"); // Wait 5 seconds...
var file2 = DownloadFile("file2.zip"); // Wait 5 seconds...
var file3 = DownloadFile("file3.zip"); // Wait 5 seconds...
// Total time: 15 seconds, program frozen the whole time
}
Asynchronous (Non-Blocking)
// THIS DOESN'T FREEZE
public async Task DownloadFilesAsync()
{
var task1 = DownloadFileAsync("file1.zip");
var task2 = DownloadFileAsync("file2.zip");
var task3 = DownloadFileAsync("file3.zip");
await Task.WhenAll(task1, task2, task3);
// Total time: 5 seconds, all download at once!
}
❌ Common Mistakes
Mistake 1: Forgetting await
// WRONG - This doesn't wait for the result!
static async Task Main()
{
var resultTask = Curl.ExecuteAsync("curl https://api.com");
Console.WriteLine(resultTask.Body); // ERROR! resultTask is a Task, not a result
}
// RIGHT - Use await to get the actual result
static async Task Main()
{
var result = await Curl.ExecuteAsync("curl https://api.com");
Console.WriteLine(result.Body); // Works! result is the actual response
}
Mistake 2: Using .Result or .Wait()
// WRONG - Can cause deadlocks!
static void Main()
{
var result = Curl.ExecuteAsync("curl https://api.com").Result; // BAD!
// or
var task = Curl.ExecuteAsync("curl https://api.com");
task.Wait(); // ALSO BAD!
}
// RIGHT - Use async/await all the way
static async Task Main()
{
var result = await Curl.ExecuteAsync("curl https://api.com"); // GOOD!
}
Mistake 3: Not Making Method Async
// WRONG - Method not async
static Task<string> GetData()
{
var result = await Curl.ExecuteAsync("curl https://api.com"); // ERROR!
return result.Body;
}
// RIGHT - Method is async
static async Task<string> GetData()
{
var result = await Curl.ExecuteAsync("curl https://api.com"); // Works!
return result.Body;
}
🎮 Interactive Example
Try this code and see the difference:
using System;
using System.Threading.Tasks;
using System.Diagnostics;
using CurlDotNet;
class Program
{
static async Task Main()
{
// Method 1: One at a time (slow)
var stopwatch = Stopwatch.StartNew();
var result1 = await Curl.ExecuteAsync("curl https://httpbin.org/delay/1");
var result2 = await Curl.ExecuteAsync("curl https://httpbin.org/delay/1");
var result3 = await Curl.ExecuteAsync("curl https://httpbin.org/delay/1");
Console.WriteLine($"Sequential: {stopwatch.ElapsedMilliseconds}ms (about 3 seconds)");
// Method 2: All at once (fast!)
stopwatch.Restart();
var task1 = Curl.ExecuteAsync("curl https://httpbin.org/delay/1");
var task2 = Curl.ExecuteAsync("curl https://httpbin.org/delay/1");
var task3 = Curl.ExecuteAsync("curl https://httpbin.org/delay/1");
await Task.WhenAll(task1, task2, task3);
Console.WriteLine($"Parallel: {stopwatch.ElapsedMilliseconds}ms (about 1 second)");
}
}
📊 Quick Reference
| Keyword | What It Does | When to Use |
|---|---|---|
async |
Marks a method as asynchronous | When method contains await |
await |
Waits for async operation | Before any ...Async() method |
Task |
Represents an ongoing operation | Return type for async methods |
Task<T> |
Ongoing operation with result | When async method returns value |
🎯 Simple Rules to Remember
- See
Asyncin method name? → Useawait - Using
awaitin method? → Mark method asasync - Method is
async? → ReturnTaskorTask<T> - Multiple operations? → Consider
Task.WhenAll()
🚀 Next Steps
Now that you understand async/await:
- Next Tutorial → Your First Request
- Practice → Try the interactive example above
- Experiment → What happens without
await?
🤔 FAQs
Q: Why not just use synchronous methods? A: Your application would freeze during network requests. Users hate frozen apps!
Q: Can I use async without await? A: Technically yes, but you usually shouldn’t. You’d lose the benefit.
Q: Is async/await faster? A: For single operations, no. For multiple operations or keeping UI responsive, yes!
Q: Do I always need async/await? A: For network requests, file I/O, and database calls - yes! For simple calculations - no.
📚 Summary
- Async = Non-blocking (doesn’t freeze)
- Await = Wait for result (but nicely)
- Always use together =
await+Asyncmethods - Mark methods =
async Taskwhen usingawait - Better user experience = Responsive applications
Ready to make your first request? → Your First Request
Still confused? That’s normal! Try the examples and it will click. Check Common Issues if you get stuck.