Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use of null check in event handler

Tags:

c#

When checking if an event handler is null, is this done on a per-thread basis?

Ensuring someone is listening to the event is done like this:

EventSeven += new DivBySevenHandler(dbsl.ShowOnScreen); 

If I add code following this pattern above where I check for null, then why would I need a null check (code taken from this site). What am I missing?

Also, what's the rule with events and GC?

like image 760
GurdeepS Avatar asked Mar 23 '09 09:03

GurdeepS


People also ask

How do you know if an event handler is null?

Event handler can not be null or not, because event handler is a piece of code, a method, anonymous or not. Only the instance of event handle can be null or not. That's it. Checking up if the event instance is null is impossible outside the class declaring the event.

What is null check in C#?

NULL checks in C# v.The question mark symbol which used in if condition, which means that it'll check whether value is NULL, if not then it'll check whether Name is null. Also, we can also do Null using Null Coalescing operator, Var test = value ?? “value is null”; C#

Why is Eventhandler null?

The event handler will be null unless somebody has subscribed to the event. As soon as a delegate is subscribed to the event, it will no longer be null. This protects you from a null exception if there has been no subscribers.

What are event handler methods?

To respond to an event, you define an event handler method in the event receiver. This method must match the signature of the delegate for the event you are handling. In the event handler, you perform the actions that are required when the event is raised, such as collecting user input after the user clicks a button.


2 Answers

The problem is that if nobody subscribes the the event, it is null. And you can't invoke against a null. Three approaches leap to mind:

  • check for null (see below)
  • add a "do nothing" handler: public event EventHandler MyEvent = delegate {};
  • use an extension method (see below)

When checking for null, to be thread-safe, you must in theory capture the delegate reference first (in case it changes between the check and the invoke):

protected virtual void OnMyEvent() {     EventHandler handler = MyEvent;     if(handler != null) handler(this, EventArgs.Empty); } 

Extension methods have the unusual property that they are callable on null instances...

    public static void SafeInvoke(this EventHandler handler, object sender)     {         if (handler != null) handler(sender, EventArgs.Empty);     }     public static void SafeInvoke<T>(this EventHandler<T> handler,         object sender, T args) where T : EventArgs     {         if (handler != null) handler(sender, args);     } 

then you can call:

MyEvent.SafeInvoke(this); 

and it is both null-safe (via the check) and thread-safe (by reading the reference once only).

like image 53
Marc Gravell Avatar answered Sep 29 '22 13:09

Marc Gravell


It's really not clear what you mean I'm afraid, but if there's the possibility of the delegate being null, you need to check that separately on each thread. Typically you'd do:

public void OnSeven() {     DivBySevenHandler handler = EventSeven;     if (handler != null)     {         handler(...);     } } 

This ensures that even if EventSeven changes during the course of OnSeven() you won't get a NullReferenceException.

But you're right that you don't need the null check if you've definitely got a subscribed handler. This can easily be done in C# 2 with a "no-op" handler:

public event DivBySevenHandler EventSeven = delegate {}; 

On the other hand, you might want some sort of locking just to make sure that you've got the "latest" set of handlers, if you might get subscriptions from various threads. I have an example in my threading tutorial which can help - although usually I'd recommend trying to avoid requiring it.

In terms of garbage collection, the event publisher ends up with a reference to the event subscriber (i.e. the target of the handler). This is only a problem if the publisher is meant to live longer than the subscriber.

like image 35
Jon Skeet Avatar answered Sep 29 '22 12:09

Jon Skeet