I've seen many developers when wanting to invoke an Event
they assign it to a local variable named handler
and invoke handler
instead of invoking Event
directly. Why we are not invoking Events directly?
private void OnSomethingChanged(EventArgs e)
{
if (SomethingEvent != null)
{
SomethingEvent(this, e);
}
}
The code you've posted isn't thread-safe, basically. If the final subscriber unsubscribes in a different thread after the if
check but before the invocation, you'll get a NullReferenceException
.
One option is to write an extension method:
public static void NullSafeInvoke(this EventHandler handler,
object sender, EventArgs e)
{
if (handler != null)
{
handler(this, e);
}
}
You can then write:
private void OnSomethingChanged(EventArgs e)
{
SomethingEvent.NullSafeInvoke(this, e);
}
You'd probably want another overload for EventHandler<T>
, too.
There is a possibility of a race condition if the event is not copied (relevant to multi-threaded applications only).
If one thread unsubscribes from the event just after the null
check leaving nothing subscribed to it, you will get a NullReferenceException
.
I also don't understand why. There is a simple and pretty safe method:
// when constructing of instance, to create empty subscription
public event EventHandler SomethingEvent = delegate { };
private void OnSomethingChanged(EventArgs e)
{
// and call it directly
SomethingEvent(this, e);
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.