C# / CHAPTER 15
Tasks, asynchronous completion, and failure
AdvancedReturn completion handles that callers can actually await.
By the end of this chapter
- Distinguish Task from async void
- Combine independent operations
- Observe failures through await
The idea
A Task represents eventual completion, and Task<T> also carries a result. An async method can run synchronously until it reaches an incomplete await. Awaiting an already completed task need not yield control. Asynchronous does not automatically mean a new thread, and it does not make CPU-heavy work free.
Return Task from ordinary asynchronous operations so callers can await completion and observe exceptions. async void is mainly for event-handler contracts and cannot provide that completion handle. Start independent tasks before awaiting their combination when concurrency is intended. Task.WhenAll preserves input order for successful result arrays and does not automatically cancel remaining work merely because one task fails.
using System;
using System.Threading.Tasks;
static async Task<int> SumAsync() {
Task<int> a = Task.FromResult(4);
Task<int> b = Task.FromResult(7);
int[] values = await Task.WhenAll(a, b);
return values[0] + values[1];
}
Console.WriteLine(await SumAsync());11
Both tasks are combined into one awaitable completion result.
Try it yourself
Write an asynchronous composition that waits for two independent values and propagates either failure.
Use your own editor for this exercise. Runnable challenges on CodeQuest are available for JavaScript, Python, and SQL.
CHECK YOUR UNDERSTANDING