Async/Await
Asynchronous programming
Introduction
In this lesson, you'll learn about async/await in C#. Coming from JavaScript, you already have a foundation for understanding this concept. We'll build on that knowledge while highlighting the key differences.
In JavaScript, 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.Threading.Tasks;
async Task<User> FetchUser(int id) {
using var client = new HttpClient();
var res = await client.GetAsync("/api/users/" + id);
res.EnsureSuccessStatusCode();
return await res.Content.ReadFromJsonAsync<User>();
}
async Task Main() {
try {
var user = await FetchUser(1);
Console.WriteLine(user.Name);
} catch (HttpRequestException ex) {
Console.Error.WriteLine(ex.Message);
}
}
// Parallel
var (a, b) = await Task.WhenAll(FetchUser(1), FetchUser(2));Comparing to JavaScript
Here's how you might have written similar code in JavaScript:
async function fetchUser(id) {
const res = await fetch("/api/users/" + id);
if (!res.ok) throw new Error("HTTP " + res.status);
return res.json();
}
async function main() {
try {
const user = await fetchUser(1);
console.log(user.name);
} catch (err) {
console.error(err);
}
}
// Parallel
const [a, b] = await Promise.all([fetchUser(1), fetchUser(2)]);You may be used to different syntax or behavior.
C# async/await is nearly identical to JS async/await
You may be used to different syntax or behavior.
C# returns Task<T> instead of JS Promise<T>
You may be used to different syntax or behavior.
Task.WhenAll replaces Promise.all
You may be used to different syntax or behavior.
C# async methods conventionally end with 'Async' suffix
Step-by-Step Breakdown
1. Task vs Promise
C# Task<T> is the equivalent of JS Promise<T>. async/await syntax is nearly identical in both languages.
async function getUser(): Promise<User>async Task<User> GetUserAsync()2. Task.WhenAll
Task.WhenAll runs multiple async operations in parallel, just like Promise.all.
const [a, b] = await Promise.all([f1(), f2()]);await Task.WhenAll(task1, task2);
var a = task1.Result; var b = task2.Result;3. Naming Convention
By convention, C# async methods end with Async (FetchUserAsync). This helps distinguish async from sync overloads.
Common Mistakes
When coming from JavaScript, developers often make these mistakes:
- C# async/await is nearly identical to JS async/await
- C# returns Task<T> instead of JS Promise<T>
- Task.WhenAll replaces Promise.all
Key Takeaways
- C# async/await mirrors JS — nearly identical syntax
- Promise<T> → Task<T>
- Promise.all → Task.WhenAll
- C# async methods end with Async by convention