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 threads subscribed to the same OperationComplete
handler and one unsubscribed the event. In such a scenario, the OperationComplete
event will become null
and for the next thread since 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 do we do? How can we make sure that our application will not come into such a 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 at 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, we will store the current value 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[^].