using System.Threading.Tasks;
var someEventRaisingObject = new SomeEventRaisingObject();
someEventRaisingObject.TheEvent += EventHandlers.TryAsync<EventArgs>(
SomeEventRaisingObject_TheEventAsync,
ex => Console.WriteLine($"[TryAsync Error Handler] Exception handler caught: {ex}"));
someEventRaisingObject.ExplicitAsyncEvent += SomeEventRaisingObject_TheEventAsync;
await someEventRaisingObject.InvokeExplicitAsync(EventArgs.Empty);
Console.WriteLine($"Caught an exception in our handler: {ex.Message}");
Console.WriteLine("Press Enter to exit");
async Task SomeEventRaisingObject_TheEventAsync(object sender, EventArgs e)
Console.WriteLine("Entering the event handler...");
await TaskThatIsReallyImportantAsync();
Console.WriteLine("Exiting the event handler...");
async Task TaskThatIsReallyImportantAsync()
throw new Exception("This is an expected exception");
delegate Task AsyncEventHandler<TArgs>(object sender, TArgs e)
static class EventHandlers
public static EventHandler<TArgs> TryAsync<TArgs>(
Func<object, TArgs, Task> callback,
Action<Exception> errorHandler)
return Task.CompletedTask;
public static EventHandler<TArgs> TryAsync<TArgs>(
Func<object, TArgs, Task> callback,
Func<Exception, Task> errorHandler)
return new EventHandler<TArgs>(async (object s, TArgs e) =>
await callback.Invoke(s, e);
await errorHandler.Invoke(ex);
class SomeEventRaisingObject
public event EventHandler<EventArgs> TheEvent;
public event AsyncEventHandler<EventArgs> ExplicitAsyncEvent;
public void Invoke(EventArgs e)
TheEvent?.Invoke(this, e);
public async Task InvokeExplicitAsync(EventArgs e)
await ExplicitAsyncEvent?.Invoke(this, e);