Asynchronous programming keeps an application from blocking while it waits for slow work, such as network or disk access. In C#, the Task Parallel Library (TPL) and the async and await keywords provide the main tools. A Task represents work that may run on the same thread or a separate thread; it does not automatically mean a new thread. section 4.4 section 4.5
Consider a title search that requests comic metadata over HTTP. Calling .Result on GetStreamAsync makes each request wait before the search continues. A Stopwatch establishes a baseline: one search took about 35 seconds when requests ran synchronously. The asynchronous approach can start several HTTP requests rather than waiting for each one in turn. Response times still vary; a slow server or throttling can make even a test run take much longer. section 4.3 section 4.4
Listing 4.34 Modifying GetComic to be asynchronous
public static async Task<Comic?> GetComicAsync( #1
int number, #2
CancellationToken cancellationToken) #3
{
if (cancellationToken.IsCancellationRequested) #4
{
return null;
}
try
{
var path = number == 0 ? "info.0.json"
: $"{number}/info.0.json";
var stream = await client.GetStreamAsync( #5
path, cancellationToken); #6
return await JsonSerializer.DeserializeAsync<Comic>( #7
stream, cancellationToken: cancellationToken); #6
}
catch (AggregateException e)
when (e.InnerException is HttpRequestException)
{
return null;
}
catch (HttpRequestException)
{
return null;
}
catch (TaskCanceledException) #8
{
return null;
}
}
Follow the conversion of a single retrieval method: its async Task<Comic?> return type, awaited HTTP stream and JSON deserialization, and cancellation token passed into both operations. The method also checks for cancellation before starting work and handles request and cancellation exceptions. section 4.4
Making one method asynchronous is only part of the change. The title search also becomes async: it creates retrieval tasks, checks their results for a matching title, and uses a cancellation token so outstanding work can be asked to stop. The calling code must then await the search instead of treating its Task as a completed comic. section 4.4
Listing 4.36 Updating Program.cs to use async method
var results = await Parser.Default #1
.ParseArguments<Options>(args)
.WithParsedAsync<Options>( #2
async options => { #3
var stopwatch = new Stopwatch();
stopwatch.Start();
var comic = await GetComicWithTitleAsync( #1
options.Title!);
stopwatch.Stop();
// Rest of code continues
});
The command-line entry point awaits both the asynchronous argument handler and the title search. Stopwatch timing remains around the operation being measured, making the revised search comparable with the synchronous baseline. section 4.4
The same reason to avoid blocking applies to database requests: EF Core work can be performed asynchronously so slow requests need not block application threads. Retries and backoff for slow or throttled responses are separate concerns, not a consequence of adding async and await. section 5.6 section 4.4



























