Async/Await
Asynchronous programming
Introduction
In this lesson, you'll learn about async/await in C#. Coming from Python, you already have a foundation for understanding this concept. We'll build on that knowledge while highlighting the key differences.
In Python, you're familiar with asynchronous programming.
C# has its own approach to asynchronous programming, which we'll explore step by step.
The C# Way
Let's see how C# handles this concept. Here's a typical example:
using System.Net.Http;
using System.Net.Http.Json;
using System.Threading.Tasks;
async Task<User> FetchUser(HttpClient client, int userId) {
return await client.GetFromJsonAsync<User>("/api/users/" + userId);
}
async Task Main() {
using var client = new HttpClient();
var user = await FetchUser(client, 1);
Console.WriteLine(user.Name);
// Parallel — like asyncio.gather
var tasks = Enumerable.Range(1, 3)
.Select(i => FetchUser(client, i));
var users = await Task.WhenAll(tasks);
}Comparing to Python
Here's how you might have written similar code in Python:
import asyncio
import aiohttp
async def fetch_user(session, user_id: int) -> dict:
async with session.get(f"/api/users/{user_id}") as res:
return await res.json()
async def main():
async with aiohttp.ClientSession() as session:
user = await fetch_user(session, 1)
print(user["name"])
# Parallel
async with aiohttp.ClientSession() as s:
tasks = [fetch_user(s, i) for i in range(1, 4)]
users = await asyncio.gather(*tasks)
asyncio.run(main())You may be used to different syntax or behavior.
C# async/await is nearly identical to Python asyncio
You may be used to different syntax or behavior.
Python asyncio.gather → C# Task.WhenAll
You may be used to different syntax or behavior.
C# Task<T> is Python's Coroutine/awaitable
You may be used to different syntax or behavior.
C# async methods conventionally end with 'Async' suffix
Step-by-Step Breakdown
1. Task vs Coroutine
C# Task<T> is the equivalent of Python's async/coroutine. The async/await keywords are nearly identical.
async def fetch(url: str) -> dict: ...async Task<User> FetchAsync(string url) { ... }2. Task.WhenAll
Task.WhenAll runs multiple async operations concurrently, just like asyncio.gather.
users = await asyncio.gather(*tasks)var users = await Task.WhenAll(tasks);3. Context Managers → using
Python's async with (async context manager) becomes C#'s using statement for resource management.
async with session.get(url) as res: ...using var client = new HttpClient();
var data = await client.GetStringAsync(url);Common Mistakes
When coming from Python, developers often make these mistakes:
- C# async/await is nearly identical to Python asyncio
- Python asyncio.gather → C# Task.WhenAll
- C# Task<T> is Python's Coroutine/awaitable
Key Takeaways
- Python async/await → C# async/await (nearly identical)
- asyncio.gather → Task.WhenAll
- Coroutine/Task<T> are equivalent
- async with → using statement