.NET Weak Event Handlers – Part II
- by João Angelo
On the first part of this article I showed two possible ways to create weak event handlers. One using reflection and the other using a delegate.
For this performance analysis we will further differentiate between creating a delegate by providing the type of the listener at compile time (Explicit Delegate) vs creating the delegate with the type of the listener being only obtained at runtime (Implicit Delegate).
As expected, the performance between reflection/delegate differ significantly. With the reflection based approach, creating a weak event handler is just storing a MethodInfo reference while with the delegate based approach there is the need to create the delegate which will be invoked later.
So, at creating the weak event handler reflection clearly wins, but what about when the handler is invoked.
No surprises there, performing a call through reflection every time a handler is invoked is costly. In conclusion, if you want good performance when creating handlers that only sporadically get triggered use reflection, otherwise use the delegate based approach.
The explicit delegate approach always wins against the implicit delegate, but I find the syntax for the latter much more intuitive.
// Implicit delegate - The listener type is inferred at runtime from the handler parameter
public static EventHandler WrapInDelegateCall(EventHandler handler);
public static EventHandler<TArgs> WrapInDelegateCall<TArgs>(EventHandler<TArgs> handler) where TArgs : EventArgs;
// Explicite delegate - TListener is the type that defines the handler
public static EventHandler WrapInDelegateCall<TListener>(EventHandler handler);
public static EventHandler<TArgs> WrapInDelegateCall<TArgs, TListener>(EventHandler<TArgs> handler) where TArgs : EventArgs;