Delegates Delegates

Here is something you may not have noticed before.

I'm sure you have utilized the following code to create an event handler in your code.

VB.NET  AddHandler MsgArrivedEvent, AddressOf My_MsgArrivedCallback
C#      MsgArrivedEvent += new MsgArrivedEventHandler(My_MsgArrivedEventCallback);

I have found it quite useful to create a method called AddHandlers and one called RemoveHandlers. This way I can easily turn on and off event handling. It's very nice when handling events like ColumnChanged in a Dataset. When I want to push data into the Dataset without the events firing I can just call RemoveHandlers. Then when I'm done call AddHandlers. It's analogous to enforceconstraints.

Here is an example in VB.

Public Sub AddHandlers()
   With Me
.OrderEntity.OrderData
      AddHandler .Order.ColumnChanged, AddressOf Me.onOrderColumnChanged
   End
With
End Sub

Public Sub RemoveHandlers()
  
With Me.OrderEntity.OrderData
      RemoveHandler .Order.ColumnChanged, AddressOf Me.onOrderColumnChanged
   End With
End Sub

If you use something like this be careful. Why you ask? You could turn Handlers on twice in a row inadvertently.

For example:
From the columnchanged event handler you call CalculateTotal which will RemoveHandlers, total the items, recalculate the tax, and then call AddHandlers.
Also from the columnchanged event handler you call CalculateTax which needs to RemoveHandlers, total the taxes for all items, and then call AddHandlers.
How clever of you to reuse the code in CalculateTax. pseudo code sample below.

CalculateTotal( amount )
  RemoveHandlers()
  'Total values
  if taxable
    CalculateTax(amount)
  AddHandlers()

CalculateTax( amount )
  RemoveHandlers()
  'Calculate tax
  AddHandlers()

The problem with this scenario is it will call RemoveHandlers twice then AddHandlers twice. The side effects are:

  1. Two handlers get added to the event, therefore the handler will be fired twice each time the event fires. 
  2. You may not have noticed to double event firring. If may call Removehandlers in another method and assume the handlers are turned off, but there is still one handler so RemoveHandler fixed problem one :) but your handler is not disabled like you thought.

There is one simple solution so you don't have to worry about it. Call RemoveHandlers at the beginning of AddHandlers.

Or be more careful.