Memory leak with event handlers

Oct 17, 2011 at 2:50 PM
Edited Oct 17, 2011 at 3:01 PM

Hi,

I'm building popup menu's dynamically and adding menu items to a menu and specifying a subroutine to fire when the menu item is clicked.  As in the below:

jobBox.AddItem("Schedule Resources", AddressOf New chldSchedule(Me, job, activeLocs).AddSchedule) 

My application works such that the screen can be refreshed, causing it to redraw and recreate the popup menus.  When this happens memory is not released. I notice that if I just add the menus and items without specifying event handlers I have no memory problems.  As far as I can tell the event handler is preventing the GC from reclaiming unused memory.  Is there something I need to do to unregister the handlers?  I've tried running the below at the start of my update routine to no avail.  The loop is going through a collection I maintain of every menu I've added to the app:

SL4PopupMenu.PopupMenuManager.MenuTriggers.Clear()
SL4PopupMenu.PopupMenuManager.Reset()

For Each mnu As SL4PopupMenu.PopupMenu In menus
   SL4PopupMenu.PopupMenuManager.UnregisterMenu(mnu)
Next
Any help would be appreciated.
EDIT: I'm using the latest version: 2.6.4
Thanks,
Todd
Coordinator
Oct 23, 2011 at 10:07 AM

Hi Todd,

I can see that you are clearing the MenuTriggers list in your code. This list however keeps a record of all elements whose event handlers need to be removed when calling the UnregisterMenu method.

Have you tried running the code without the first 2 lines?

Regards

Ziad

Oct 24, 2011 at 7:02 PM

Thanks Ziad,

Actually what I did to fix it was change what I tied to the event.  Instead of the following line...

jobBox.AddItem("Schedule Resources", AddressOf New chldSchedule(Me, job, activeLocs).AddSchedule) 

I used the following...

jobBox.AddItem("Schedule Resources", Sub() OpenSchedule(job))

Sub OpenSchedule(ByVal job As get_active_locations_Result)
        Dim chld As New chldSchedule(Me, job, activeLocs)
        chld.AddSchedule()
End Sub

I think because I tied the even to just a sub routine instead of a new instance of a class it allowed it to be cleaned up by the GC.  I'm still not entirely sure on why, but it seems to work.  So I think the problem was more on my end than an issue with SL4popup menu.  I do still, however, need to keep a collection of all my menus and loop through them to get rid of them.  I do still notice a memory leak if I don't, just not nearly as bad as before.  Should that be necessary?

Thanks,

Todd

Coordinator
Nov 11, 2011 at 12:21 AM
Edited Nov 11, 2011 at 12:34 AM

Well you don't need to keep track of your menus since the PopupMenuManager is already there for it. The MenuTriggers property lets you access all registered menus and their respective trigger element(s). The menu destructor uses this list to remove all trigger events associated with it and it is only cleared after the navigation path has changed. Wihtout it the GC wouldn't be able to do its job properly. But you can simulate this by using the following line of code every time you refresh your app:

For Each mt in menuTriggers
UnregisterMenu(mt.PopupMenuBase)
Next

May be it would be better that you just add it to the Reset() method but again make sure that the MenuTriggers property is cleared last.

Cheers

Ziad