Connecting Tech Pros Worldwide Forums | Help | Site Map

Fun with delegates and events

Newbie
 
Join Date: May 2007
Posts: 8
#1: Aug 29 '08
Hi everybody,

I am currently working on a C# project, but I am kind of stuck. If anybody can give me a hand with this I would really appreciate it.

We are trying to build an application with a user GUI. When I click button1 I want to call another method to do some work and when it is done, it should callback via a delegate. Unfortunately it is giving me the error “Object reference not set to an instance of an object.”. This should not be too complicated, but somehow I am not able to resolve this myself.

This is my code:

=== BEGIN GUI CODE ===
Expand|Select|Wrap|Line Numbers
  1. public delegate void ButtonsServerTreeViewDelegate(object sender);
  2. private void button1_Click(object sender, EventArgs e)
  3. {
        // Setup listener, for updating the GUI...
  4.     DiscTreeView DiscTreeViewObject = new DiscTreeView();
  5.     DiscTreeViewObject.ButtonsServerTreeView += new ButtonsServerTreeViewDelegate(CallbackButtonsServerTreeView);
  6.  
  7.   //  DiscTreeViewObject.LoadServerTreeView();
  8.     PathSelectionTreeView.LoadServerTreeView();}
  9.  
  10. public void CallbackButtonsServerTreeView(object sender)
  11. {
        label31.Text = "HI";
    }
=== END GUI CODE ===

==== BEGIN OTHER CLASS CODE ====
Expand|Select|Wrap|Line Numbers
  1. public event ButtonsServerTreeViewDelegate ButtonsServerTreeView;
  2. public void LoadServerTreeView()
  3. {
       ButtonsServerTreeView(this);
    }
==== END OTHER CLASS CODE ====

Note that the LoadServerTreeView is called with PathSelectionTreeView and not with the DiscTreeViewObject (commented out), since PathSelectionTreeView contains my TreeView.

Is there anyway to perform the callback, if I call my LoadServerTreeView via PathSelectionTreeView ?

Again, any help is greatly appreciated.

Warm Regards,

Jan

balabaster's Avatar
Moderator
 
Join Date: Mar 2007
Location: Canada
Posts: 757
#2: Aug 29 '08

re: Fun with delegates and events


At what line are you getting that exception? It seems that you are referencing a property or method of an object that you haven't instantiated or is currently set as null or nothing...
Newbie
 
Join Date: May 2007
Posts: 8
#3: Aug 31 '08

re: Fun with delegates and events


Now I know that the exception occurs because ButtonsServerTreeView is null. I know how to prevent the event from being send, but is there some kind of way I can send events from the LoadServerTreeView ?
vekipeki's Avatar
Expert
 
Join Date: Nov 2007
Posts: 231
#4: Aug 31 '08

re: Fun with delegates and events


Actually, you MUST check if your event is non-null before invoking it - the usual way is to do it like this:

Expand|Select|Wrap|Line Numbers
  1.       public event ButtonsServerTreeViewDelegate ButtonsServerTreeView;
  2.       public void LoadServerTreeView()
  3.       {
  4.              ButtonsServerTreeViewDelegate handler = ButtonsServerTreeView;
  5.              if (handler != null)
  6.                  handler(this);
  7.       }
The whole point of using events is that your event-firing class should never know or care who and when will subscribe to any of its events (e.g. a button control has many events but in most cases you will only handle the MouseClick event).

Also note that the event handler in code snippet above is first referenced by a temporary handler variable, to avoid a race condition when another thread can unsubscribe from your event just after you have checked that it is not null. This way your still have a valid reference to a handler which gets executed anyway.

Another solution would be to create an empty delegate instance in your delegate chain just to assure that your event is never null:

Expand|Select|Wrap|Line Numbers
  1.       public event ButtonsServerTreeViewDelegate ButtonsServerTreeView = delegate { };
  2.       public void LoadServerTreeView()
  3.       {
  4.              ButtonsServerTreeView(this);
  5.       }
The latter solution gives a slight overhead when executing it, but makes your code slightly cleaner. And it's easier to just go through your existing code and add " = delegate {}; " to all your events :o).
Reply