An exception is an object representing an abnormal condition that interrupts normal execution. The runtime searches the call stack for a matching catch clause; without one, the program crashes. section 12.1
Asynchronous execution changes how exceptions travel:
- Callbacks and continuations run later, often on another thread, so their runtime call stack does not match the caller’s source-code structure. section 12.0 section 12.1
- The compiler catches exceptions inside async methods and stores them in the returned Task; await rethrows the failure in the continuation. section 12.5
- Without await, inspect or otherwise handle the Task yourself; ignoring it can lose the exception, while Task.Exception may contain an AggregateException. section 12.5
- Handle every exception inside async void methods because no Task exists to store it; an uncaught exception bubbles into the SynchronizationContext and may crash the program. section 12.4
- Use OperationCanceledException or CancellationToken.ThrowIfCancellationRequested when cancellation should interrupt work without consuming the method’s normal return value. section 9.2
Handling an async event-handler failure
A fire-and-forget UI event handler cannot report completion or failure through a Task. Catch exceptions at the boundary instead of allowing them to escape. section 3.4
Listing 3.6 async event handler with error handling
private async void Button1_Click(object sender, EventArgs ea)
{
try
{
var text = await File.ReadAllTextAsync("source.txt");
await File.WriteAllTextAsync("dest.txt", text);
}
catch(Exception ex)
{
// Do something with the exception
}
}
Inspect the complete async event-handler pattern, including asynchronous file operations and a local catch block. section 3.4
























