async and await
async and await let a C# method wait for slow work without holding a thread. Follow one real program line by line: an async method runs normally until it awaits an unfinished Task, then saves its place and returns that Task to its caller at once. The caller keeps working, and when the timer fires, a thread-pool thread resumes the method, completes the Task and hands its result to the await. The output is Start, Fetch, Working, Data.
5 quick questions
Pick an answer to see why. Your score saves with your progress.
01In what order does the program print its four lines?
GetAsync runs on the caller's thread until its first await, so Fetch comes right after Start. At await Task.Delay it returns an unfinished task, so Main prints Working. Data comes about 1000 ms later.
02What does GetAsync give back to line 2 the moment it reaches await Task.Delay(1000)?
When an async method awaits a task that is not complete, it saves its place and returns its own Task to the caller right away. The string arrives later, when the task completes.
03What does await do when the task it is given is not finished yet?
await pauses the method, not the thread. The compiler's state machine remembers where to resume, and the continuation runs once the task completes.
04In this console app, which thread runs return "Data" after the delay?
A console app has no SynchronizationContext, so continuations run on thread-pool threads. A desktop UI would resume on its UI thread instead.
05Why should you write await job instead of job.Result?
Reading .Result (or calling .Wait()) on an unfinished task blocks the thread, which wastes it and can deadlock. await frees the thread while it waits.
Glossary
- Thread
- A worker that runs code one statement at a time. A program starts with one main thread and can use more.
- Task / Task<T>
- An object that stands for work that finishes later. Task<T> also carries a result of type T once IsCompleted is true.
- async
- A modifier that lets a method use await. An async method usually returns Task or Task<T>; without any await it runs synchronously (warning CS1998).
- await
- Waits for a task without blocking the thread: if the task is unfinished, the method saves its place and returns; when the task completes, the method resumes and await gives back the result.
- Continuation
- The rest of a method after an await. It runs when the awaited task completes.
- Thread pool
- A set of worker threads that .NET keeps ready for short jobs; in a console app, continuations run on them.
- State machine
- The object the compiler turns an async method into. It stores the method's local variables and which await it is paused at.
Notes and sources
- The program is real C#. Put the 11 lines in Program.cs (a blank line between the two parts) and dotnet run prints Start, Fetch, Working, Data, the last line about 1000 ms after the others.
- Top-level statements that use await become an async Main that returns a Task. The hidden entry point that starts it simply waits for that Task, so the console program ends only after line 5. In an app with a window, the freed thread would go back to drawing it.
- Which thread runs a continuation depends on the SynchronizationContext. A console app has none, so continuations run on thread-pool threads; a desktop UI resumes on its UI thread. The figure shows one pool thread; in reality Main may resume on the same or another pool thread.
- Task.Delay(1000) completes after at least about 1000 ms; the exact moment depends on the system clock's resolution. Lines 1 to 4 take only microseconds, so the timer has barely started when Main pauses.
- Saving its place is real: the compiler rewrites every async method into a state machine object that stores the method's local variables and which await it is paused at.
- Microsoft Learn: Asynchronous programming with async and await
- Microsoft Learn: Asynchronous programming scenarios
- Microsoft Learn: Task asynchronous programming model
- Microsoft Learn: async (C# reference)
- Microsoft Learn: await operator
- Microsoft Learn: Async return types
- Microsoft Learn: Task.Delay method
- Microsoft Learn: Task<TResult> class
- Microsoft Learn: Consuming the Task-based Asynchronous Pattern
- Microsoft Learn: The managed thread pool
- Microsoft Learn: Top-level statements
Quiz Unlocks after the last step.