Back to results for “Async await”
C# › Delegates, Events & Lambdas

How would you implement a custom EventHandler using async/await, avoiding the common 'async void' anti-pattern while still matching the standard EventHandler delegate signature?

Advanced

Answer

Since standard .NET events require a 'void'-returning delegate signature, an async event handler is FORCED to be 'async void' — this is the ONE legitimate, accepted use case for async void in C#, but you should still wrap the handler's body in a try/catch, since an unhandled exception in an async void method crashes the process rather than being awaitable/catchable by the caller.
button.Clicked += async (sender, e) => {
  try {
    await SaveDataAsync(); // legitimate async void usage: matches EventHandler's signature
  } catch (Exception ex) {
    Console.WriteLine($"Error in click handler: {ex.Message}"); // must catch here -- caller can't
  }
};
Real-world example Handling a UI button click that needs to perform an asynchronous save operation, while still safely catching any resulting exceptions.

Common follow-ups: Why can't a caller catch an exception thrown from inside an 'async void' method the normal way, unlike an 'async Task' method?