Reading — step 1 of 6
Learn
async/await Basics
A thread that calls a blocking API — file read, HTTP request, database query — sits idle until the response arrives. async/await lets that thread go do other work in the meantime, while your code still reads top-to-bottom like ordinary synchronous code.
using System.Threading.Tasks;
// db and api are stand-ins for real services
static async Task<int> FetchUserAge(int id) {
var user = await db.GetUserAsync(id); // I/O — method suspends here
var profile = await api.GetProfileAsync(user);
return profile.Age;
}
At each await, if the task isn't finished yet, the method SUSPENDS: control returns to the caller, and the rest of the method is scheduled to continue when the awaited task completes. No thread sits parked. Under the hood the compiler rewrites the method into a state machine — that's why the async keyword exists: it opts the method into that transformation.
The rules
- An
asyncmethod returnsTask(no result),Task<T>(a result of type T), or — only for event handlers —void. await someTaskunwraps the task: awaiting aTask<int>yields anint. If the task failed,awaitre-throws the exception, so ordinarytry/catchworks.awaitis only legal inside a method markedasync.return 42;inside anasync Task<int>method — the compiler wraps the value into the task for you.
Trap 1: async void
An async void method can't be awaited, and its exceptions can't be caught by the caller. The entry point matters too: this course's exercises run static async Task Main() (supported by the Mono compiler behind the grader). If you change it to async void Main, the process can exit before your awaited work finishes — and print nothing.
Trap 2: blocking on tasks
int age = FetchUserAge(42).Result; // BAD — blocks, can deadlock
int age = await FetchUserAge(42); // right
.Result and .Wait() block the calling thread until the task completes. In UI or classic ASP.NET contexts that's a classic deadlock: the task's continuation needs the very thread you just froze. Inside async code, always await. (The "Tasks in Parallel and Cancellation" lesson later in this course digs into the deadlock mechanics and ConfigureAwait.)
Sequential vs parallel awaiting
var w1 = await GetWeatherAsync("NYC"); // waits for NYC...
var w2 = await GetWeatherAsync("London"); // ...THEN starts London
var t1 = GetWeatherAsync("NYC"); // both in flight already
var t2 = GetWeatherAsync("London");
var both = await Task.WhenAll(t1, t2); // total time = max, not sum
Awaiting one-by-one silently serializes independent work. Start the tasks first, then await them — the parallel-tasks lesson covers orchestration in depth.
Your exercise
Implement static async Task<int> SumAsync(int[] nums): first await Task.Delay(10); (a stand-in for real I/O), then return the sum — nums.Sum() works (System.Linq is already imported), or write a plain foreach loop. Main reads space-separated integers and prints the awaited result.
For input 1 2 3 4 5 the grader expects exactly:
15
Bare number, nothing else. The grader-caught mistakes:
- Leaving the starter's placeholder
return 0;in place — every test fails, printing0instead of15,60,42. - Changing
Maintoasync void— the process can exit duringTask.Delay(10)and print nothing at all. - Adding a label —
sum: 15fails. It'sConsole.WriteLine(total): the number alone on its line.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…