C# from Basics to Mastery — Part 8
Constructing asynchronous tasks with async and await
The articles written on this blog were created with the goal of teaching. Also, the information in the article may be incorrect, so please be careful.
Blocking a thread while waiting for a network or file operation can also freeze the screen and other operations. async and await express the waiting task so that it can be executed continuously.
Returning Task
async Task<PlayerData> LoadPlayerAsync(
string url,
CancellationToken cancellationToken)
{
using HttpResponseMessage response =
await httpClient.GetAsync(url, cancellationToken);
response.EnsureSuccessStatusCode();
PlayerData? data = await response.Content
.ReadFromJsonAsync<PlayerData>(cancellationToken);
return data ?? throw new InvalidDataException("Player data is empty");
}
When you encounter await, you can continue with the rest of your code later instead of holding on to the current thread until the task is finished. Async methods basically return a Task so that the caller can observe completion and failure.
Cancel Forward
using var source = new CancellationTokenSource(TimeSpan.FromSeconds(5));
try
{
PlayerData data = await LoadPlayerAsync(url, source.Token);
}
catch (OperationCanceledException)
{
Console.WriteLine("Loading canceled");
}
Cancel is not a function that forcibly terminates a thread. A contract that requests a task to verify a token and abort at a safe point.
Waiting for multiple tasks
Task<ItemData> itemTask = LoadItemsAsync(token);
Task<QuestData> questTask = LoadQuestsAsync(token);
await Task.WhenAll(itemTask, questTask);
ItemData items = await itemTask;
QuestData quests = await questTask;
Waiting tasks that do not depend on each other can be started first and then wait together. Simply marking a CPU computation as async does not automatically make it parallel.
flow to avoid
Synchronous waiting with Task's .Result or .Wait() can block threads or create a deadlock depending on the execution environment. It is better to continue the call path async as far as possible.
async void should be avoided except in event handlers because the caller cannot wait for completion and exceptions. The key to asynchronous code is not to add keywords, but to convey the flow of completion, failure, and cancellation to the caller.