Question Cannot access a disposed object.

gchq

Well-known member
Joined
Dec 14, 2007
Messages
168
Programming Experience
10+
When a tab panel is loading I have the following lines of code

VB.NET:
            If MainSS Is Nothing Then
                MainSS = New CustomControl.SS_Label
            End If
            TabPanel.Controls.Add(MainSS)

On rare occasions it will throw an error

Cannot access a disposed object.
Object name: 'SS_Label'.
at System.Windows.Forms.Control.CreateHandle()
at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
at System.Windows.Forms.Control.CreateControl()
at System.Windows.Forms.Control.ControlCollection.Add(Control value)


Any idea where I should be looking? As you can see I am testing to see if it exists (or creating a new control) before adding it..

=====================================================

Added 16:08 UTC

I was under the impression that once an object was disposed of, it was set to nothing - clearly that is not the case

If there any way I can check for IsDisposed within the New() Sub in my Custom Control Class?
 
Last edited:
I was under the impression that once an object was disposed of, it was set to nothing - clearly that is not the case
When you dispose an object you should also release all references to it, in order for the object to be garbage collected.
As you indicate, base Control class has a IsDisposed property that can be checked to see if a control reference has been disposed or not.
If there any way I can check for IsDisposed within the New() Sub in my Custom Control Class?
It is not clear what you mean by this.
 
Hi John

Thanks for your reply...

I have added the following to the class....


VB.NET:
Public Class SS_Label
        Inherits Label
        [COLOR="#00FF00"]Implements IDisposable[/COLOR]    
        Public Sub New()
            Me.BackColor = Color.DarkBlue
            Me.ForeColor = Color.White
            Me.Dock = DockStyle.Bottom
            Me.TextAlign = ContentAlignment.MiddleLeft
        End Sub

       
       [COLOR="#00FF00"] Public Overloads Sub Dispose()
            If Me.IsDisposed = True Then

            End If
        End Sub[/COLOR]

    End Class

What would I need to add to Me.IsDisposed?
 
Label class already implements IDisposable, and handles all that. No need to add anything to that, and adding "Implements IDisposable" has no effect.
If you did need to add anything to the base disposing code you would either override the existing Dispose method or handle the Disposed event.
It is also not the internal state that you have to take care of after disposing an object, it is external references to that object. If you come to the point where you have a variable pointing to a disposed object, that means you have a reference that was not released when the object was disposed.
 
If you come to the point where you have a variable pointing to a disposed object, that means you have a reference that was not released when the object was disposed.

How would I handle that?

By trial and error I did find a combination of opening and closing a sequence of tabs would cause the error, and resolved it for now by inserting the following at the root of all the SelectedTabChanged events...


VB.NET:
 If MainSS.IsDisposed = True Then
            MainSS = Nothing
        End If
 
How would I handle that?
If you have code that disposes an object, then you can at the same time set persistant references (like private/shared fields) to that object to Nothing.
 
objectReference.Dispose()
objectReference = Nothing

where objectReference is not a local variable about to go out of scope obviously.
 
Back
Top