This repository contains a .NET Standard 2.0 implementation for Deferred Events.
Deferred Events allows event invocators to await for the asynchronous completion of all event handlers.
Install the NuGet package by running the following command:
Install-Package DeferredEvents
Start by adding the namespace to your code files:
using DeferredEvents;
Change your events signature so that they can use DeferredEventArgs
instead of EventArgs
:
// before
public event EventHandler MyEvent;
// after
public event EventHandler<DeferredEventArgs> MyEvent;
If you have a custom event arguments class inheriting from EventArgs
, just make it inherit from DeferredEventArgs
instead.
Last step is to change the way you make your invocations:
// before
MyEvent?.Invoke(sender, EventArgs.Empty);
// after
await MyEvent.InvokeAsync(sender, new DeferredEventArgs());
The InvokeAsync()
method is an extension method that will enable you to ensure we wait for the event handlers to finish their work before we proceed.
Last step will be to change the event handlers code so it can take advantage of the deferred execution:
// before
public void OnMyEvent(object sender, EventArgs e)
{
// code
}
// after
public async void OnMyEvent(object sender, DeferredEventArgs e)
{
var deferral = e.GetDeferral();
// awaiteable code
deferral.Complete();
}
You can also use the using
pattern if you prefer:
// after
public async void OnMyEvent(object sender, DeferredEventArgs e)
{
using (e.GetDeferral())
{
// awaiteable code
}
}
You only need to call e.GetDeferral()
if you actually want to the event caller to wait for the completion of the event handler; if you don't call it, it will just behave as a regular event handler.
You must call e.GetDeferral()
to get an EventDeferral
instance before any await
call in your code to ensure that the event caller knows that it should wait for deferral.Complete()
; ideally, it should be the first thing you do in the event handler code.
If you have indeed called e.GetDeferral()
, then you must call deferral.Complete()
to signal that the event handler has finished.