No Symbols error/Stackoverflow error


Author
Message
Greg McGuffey
Greg McGuffey
Strategic Support Team Member (3.4K reputation)
Group: Forum Members
Posts: 2K, Visits: 6.6K
I've started getting an error when I go to close down my app. The first thing I see is a "No Symbols" dialog...

When I close this, I receive this error:

After some investigation, I discovered that is a problem with how I'm disposing of a control I subclassed, but I don't know why.

I have a subclassed TreeView control that calls Dispose on a class that implements IDisposable.  The TreeView calls the Dispose of the internal object, that object does it's dispose business, returns to the TreeView, which when it hits end sub, immediately jumps back into the Dispose method of the internal object. My subclassed TreeView is called DataTreeView. It has a data provider, called MyDataProvider, which implements IDisposable. Here is an example of what I'm seeing:

System.ComponentModel.Component.Finalize()
--calls-->DataTreeView.Dispose(False)
--calls--> MyDataProvider.Dispose()
--calls--> MyDataProvider.Dispose(True) 
--back out to--> MyDataProvider.Dispose()
--back out to--> DataTreeView.Dispose(False)
--??--> MyDataProvider.Dispose(True)

To make things weirder, that last step doesn't halt on the first line of code, but on a line with a break point, although I hit F11. 

Now, while debugging this, trying to compose this message, it stopped causing errors, even though it still goes through the above cycle 6-8 times.

Any ideas what's going on? I'm throughly confused  Crazy

Thanks!

StrataFrame Team
S
StrataFrame Developer (4.3K reputation)StrataFrame Developer (4.3K reputation)StrataFrame Developer (4.3K reputation)StrataFrame Developer (4.3K reputation)StrataFrame Developer (4.3K reputation)StrataFrame Developer (4.3K reputation)StrataFrame Developer (4.3K reputation)StrataFrame Developer (4.3K reputation)StrataFrame Developer (4.3K reputation)
Group: StrataFrame Developers
Posts: 3K, Visits: 2.5K
Can you post the Dispose(ByVal disposing As Boolean) code from your custom control?  Most likely, you're just re-calling Dispose() somewhere in there and it's getting itself into a recursive loop.  99.999% of the time, if you get a StackOverflowException, it's because you've gotten yourself into a recursive loop.  The "stack" it's talking about in the StackOverflowException is the callstack.  CLR lets the callstack grow, but eventually, it reaches the point where it just kills it because it knows that the stack got too big.
Greg McGuffey
Greg McGuffey
Strategic Support Team Member (3.4K reputation)
Group: Forum Members
Posts: 2K, Visits: 6.6K
Thanks Ben. Here is the code from my control and from the class that it is trying to dispose. I've annotated with comments to try and show the flow:



'-- From DataTreeView control

Public Class DataTreeView

Inherits TreeView

' ....other code not shown

#Region " IDisposable Overrides "

Private _isDisposing As Boolean = False

'-- Dispose of additional resources used by this subclass.

Protected Overrides Sub Dispose(ByVal disposing As Boolean)

If Not Me._isDisposing Then

'-- Clean up the menu

Me.ClearContextMenu()

'-- Dispose of the IDataProvider

' The DataSource property references another class that implements

' the IDataProvider interface (my own interface). This property determines

' if the specific provider implements the IDisposable interface.

If Me.DataSource.CanDispose Then

'-- Dispose of this item

DirectCast(Me.DataSource, IDisposable).Dispose() '<-- called MyDataProvider.Dispose()

End If

End If

'-- Flag that disposing has already been called.

Me._isDisposing = True

'-- Clean up base object

MyBase.Dispose(disposing)

End Sub '<-- when reached, code jumped to MyDataProvider.Dispose(true)

#End Region

End Class




The DirectCast(Me.DataSource, IDisposable).Dispose() calls into the following code:

'-- From the class that implements the IDataProvider interface.

' An instantiated object of this class is set as the DataSource in the DataTreeView.

Public Class MyDataProvider

Implements IDataProvider, IDisposable

' other code not shown...

#Region " IDisposable Implementation "

'-- Detect redunant calls to the Dispose method.

Private disposedValue As Boolean = False

'-- Method that actually disposes of any resources.

Protected Overridable Sub Dispose(ByVal disposing As Boolean)

If Not Me.disposedValue Then

If disposing Then

'-- Remove event handler, if the provider has been created

' In my tests, this was called before this provider was set

' i.e. _anotherProvider was nothing

If _anotherProvider IsNot Nothing Then

RemoveHandler _mitaModelProvider.NodeAdded, AddressOf Me.MitaModelProvider_NodeAdded

'-- Dispose of provider

Me.AnoterDataProvider.Dispose()

End If

End If

End If

Me.disposedValue = True

End Sub



'-- Cleanup this object and dispose of any resources.

Public Sub Dispose() Implements IDisposable.Dispose

' Do not change this code. Put cleanup code in Dispose(ByVal disposing As Boolean) above.

Dispose(True)

GC.SuppressFinalize(Me)

End Sub

#End Region




Thanks for looking at this Ben.
StrataFrame Team
S
StrataFrame Developer (4.3K reputation)StrataFrame Developer (4.3K reputation)StrataFrame Developer (4.3K reputation)StrataFrame Developer (4.3K reputation)StrataFrame Developer (4.3K reputation)StrataFrame Developer (4.3K reputation)StrataFrame Developer (4.3K reputation)StrataFrame Developer (4.3K reputation)StrataFrame Developer (4.3K reputation)
Group: StrataFrame Developers
Posts: 3K, Visits: 2.5K
Technically, you're not supposed to call another classes Dispose() from within your own Dispose(False) (when False is passed as the disposing value).  Mainly because False is passed when the object is being finalized by the GC, meaning that half of it's managed resources might have already been cleaned up.  So, in your DataTreeView.Dispose(ByVal disposing As Boolean), make sure that you don't call the Dispose() on your data provider unless the disposing argument is True.  Only clean up managed resources if the disposing argument is True.  And if you're worried about getting the data provider disposed if you don't call it... don't worry about it.  The GC will still take care of it.

http://msdn.microsoft.com/msdnmag/issues/07/07/CLRInsideOut/

http://www.bluebytesoftware.com/blog/PermaLink.aspx?guid=88e62cdf-5919-4ac7-bc33-20c06ae539ae

GO

Merge Selected

Merge into selected topic...



Merge into merge target...



Merge into a specific topic ID...




Similar Topics

Reading This Topic

Login

Explore
Messages
Mentions
Search