Tips & Tricks - Working with Event Handler


Sometimes we write the following code while working with EventHandler and that may create some problems. I will discuss this later on. Let us see the code:


                private void RaiseOperationComplete(EventArgs e)
                {
                    if(OperationComplete != null)
                    {
                        OperationComplete(this, e);
                    }
                }



In the above case, suppose two thread subscribed to the same OperationComplete handler and one unsubscribed the event. In such scenario the OperationComplete event will become null and for the next thread due to the event is null it will not execute. This happens mainly in multithreaded applications but you can't guarantee for single threaded application too.

So what to do? How can we make sure that our application will not come into such situation and work properly?



Yup, let us modify the code a bit. First we will store the event handler to a local variable and then we will raise the event from the locally cached copy. Have a look into the following code:

                private void RaiseOperationComplete(EventArgs e)
                {
                    EventHandler<string> handler = OperationComplete;
                    if(handler != null)
                    {
                        handler(this, e);
                    }
                }



Here when we execute the OperationComplete event handler, the current value we will store in a local variable named "handler". Hence both "handler" and "OperationComplete" will point to the same object. Thus we will create a cached copy of the same value for the handler and then raise the event.

The reason you do this is because the assignment is a copy of the delegate instance at that point, and not a by-value copy. Doing this, the reference will be cached just in case another thread, or re-entrant code, nulls out the reference before you call it. The original value will not change though it will set the event to null.

So, remember to always follow the second approach and be in the safer place of coding.
Thanks to Pete O'Hanlon for bringing this to my point in this post.

If you have come this far, it means that you liked what you are reading. Why not reach little more and connect with me directly on Twitter, Facebook, Google+ and LinkedIn. I would love to hear your thoughts and opinions on my articles directly. Also, don't forget to share your views and/or feedback in the comment section below.

2 comments

  1. Another option I use is to add an empty delegate to the event in the constructor.

    Something like: OperationComplete += (obj,e) => {};

    That way it is never null, right?

    ReplyDelete
  2. Yes, as you are using the Anonymous event handler hence in this case you don't have to worry about. It will be handle automatically.

    ReplyDelete

 
© 2008-2016 Kunal-Chowdhury.com - Microsoft Technology Blog for developers and consumers | Designed by Kunal Chowdhury
Back to top