Persistant User controls and out of memory exception

dmvprof

Member
Joined
Dec 9, 2010
Messages
12
Programming Experience
Beginner
I have a Winform application that I am using with WCF and SQL. Part of the program that the users use to create a report will dynamically create custom user controls and place a reference to them into a hashtable that I maintain. Then as the user navigates through the report by selecting nodes on a treeview, I load and unload the User Controls into a panel.

Here is the code I use to create them and place them into the Collection

VB.NET:
       ucIncidentInstance = New ucIncidentMR(IncidentReport, IncidentReportGUID)
        ucIncidentInstance.Tag = "IncidentMR"
        ucIncidentInstance.Dock = DockStyle.Fill
        Globals.ControlTable.Add(IncidentReportGUID, ucIncidentInstance)
        Globals.GlobalNode.Nodes.Add(IncidentReportGUID, "Incident Report")

Here is the code that moves them in and out of the Panel on the form as the user navigates through the treeview

VB.NET:
        If Globals.ControlTable.ContainsKey(e.Node.Name) Then
            panelMain.Controls.Clear()
            panelMain.Controls.Add(CType(Globals.ControlTable(e.Node.Name), UserControl))
        Else
            If e.Node.Name = "MainNode" Then
                panelMain.Controls.Clear()
            End If
        End If

And here is the code I use in the forms ?Closing? event to try to clean up the memory when the User closes this case. I?ve done it with and without the ?.Dispose()? line and the ?= Nothing? line. This code does get executed but doesn?t seem to help.

VB.NET:
        For Each item As DictionaryEntry In Globals.ControlTable

            If item.Key = IncidentReportGUID Then
               Dim myControl As ucIncidentMR
                myControl = CType(Globals.ControlTable(item.Key), ucIncidentMR)
                myControl.Dispose()
                myControl = Nothing
            End If

        Next


When I go into a memory profiler, the controls stay in memory even though the form that created them has been unloaded from memory. The profiler reports that the control listed above has held memory of 8818k. When a report is closed and another is opened, the held memory for this control increases by 8818k. And continues to increase by that amount for each report that is opened. As you can imagine, people opening and closing a lot of reports eventually get an out of memory exception.
 
More info. I have one type of custom control that does get removed when the form closes I have no idea what is different aout it.
 
First of all, you shouldn't be using a Hashtable. Use a generic Dictionary. I guess your keys are Strings and, if there's no more specific type, your values are all UserControls at least. That means that you can use a Dictionary(Of String, UserControl). When it's time to clean up, this should be all you need:
For Each item In myDictionary
    item.Value.Dispose()
Next

myDictionary.Clear()
 
First of all, you shouldn't be using a Hashtable. Use a generic Dictionary. I guess your keys are Strings and, if there's no more specific type, your values are all UserControls at least. That means that you can use a Dictionary(Of String, UserControl). When it's time to clean up, this should be all you need:
For Each item In myDictionary
    item.Value.Dispose()
Next

myDictionary.Clear()

I'm following your suggestion, and will post results, but in the meantime, I'm just curious about why not a hashtable?
 
I'm following your suggestion, and will post results, but in the meantime, I'm just curious about why not a hashtable?

I replaced the hash table with the dictionary, but the behavior didn't change.

I'm still hung up on the fact that one of the controls is being removed and several others remain. I don't see anything obviously different with it.
 
I'm following your suggestion, and will post results, but in the meantime, I'm just curious about why not a hashtable?

For the same reason that you should use a List(Of T) and not an ArrayList. It's not .NET 1.1 any more.
 
I replaced the hash table with the dictionary, but the behavior didn't change.

I'm still hung up on the fact that one of the controls is being removed and several others remain. I don't see anything obviously different with it.

What exactly do you mean by "removed"?
 
It is also worth noting that disposing a control does not immediately free the memory of that object, only when the garbage collector takes the round does that happen - if the object space can be claimed at that time. Disposing frees unmanaged resources and mark the object disposed and to not be finalized, which makes the eventual GC process faster.
 
Back
Top