M
Matthew Herrmann
Hi,
I've heard from groups that listeners to event handlers cause
references to be kept alive, if the targets are marked to stay alive. I
need to make sure that attaching events to objects will not cause them
to be kept open.
I created a test which has "target" listening to "source" for events.
After plugging source into target, I then let go of source. Since I'm
still holding onto target, if delegates were a strong reference, then
target shouldn't be collected. What I find is that it _is_ being
garbage collected, which is what I want.
If I add a normal reference to source from target, then the garbage
collection does not fire, as I expect.
Am I missing something? Why am I seeing a weak reference behaviour for
event delegates when others seem to witness strong referencing? Is this
an event vs delegate issue? Having tested this behaviour, I am about to
rely upon this in a design.
TIA,
Matthew Herrmann
Far Edge Pty Ltd
http://www.faredge.com.au/
----------------
Public Module Startup
Public Sub Main()
Dim target As New Target
Dim source As Source
source = New Source
'target.Reference = test
AddHandler source.Blah, AddressOf target.Blah
source.Fire()
MsgBox("Created")
MsgBox("Is cleaned up? " & Finalized)
source = Nothing
GC.Collect()
GC.WaitForPendingFinalizers()
MsgBox("Is cleaned up? " & Finalized)
' Test call to target, it still exists
target.Blah(Nothing, New EventArgs)
MsgBox("Finished.")
End Sub
Public Finalized As Boolean = False
End Module
Friend Class Source
Public Event Blah As EventHandler
Protected Overrides Sub Finalize()
Finalized = True
MyBase.Finalize()
End Sub
Public Sub Fire()
RaiseEvent Blah(Me, New EventArgs)
End Sub
End Class
Friend Class Target
Public Reference As Source
Public Sub Blah(ByVal sender As Object, ByVal e As EventArgs)
MsgBox("Fired!")
End Sub
End Class
I've heard from groups that listeners to event handlers cause
references to be kept alive, if the targets are marked to stay alive. I
need to make sure that attaching events to objects will not cause them
to be kept open.
I created a test which has "target" listening to "source" for events.
After plugging source into target, I then let go of source. Since I'm
still holding onto target, if delegates were a strong reference, then
target shouldn't be collected. What I find is that it _is_ being
garbage collected, which is what I want.
If I add a normal reference to source from target, then the garbage
collection does not fire, as I expect.
Am I missing something? Why am I seeing a weak reference behaviour for
event delegates when others seem to witness strong referencing? Is this
an event vs delegate issue? Having tested this behaviour, I am about to
rely upon this in a design.
TIA,
Matthew Herrmann
Far Edge Pty Ltd
http://www.faredge.com.au/
----------------
Public Module Startup
Public Sub Main()
Dim target As New Target
Dim source As Source
source = New Source
'target.Reference = test
AddHandler source.Blah, AddressOf target.Blah
source.Fire()
MsgBox("Created")
MsgBox("Is cleaned up? " & Finalized)
source = Nothing
GC.Collect()
GC.WaitForPendingFinalizers()
MsgBox("Is cleaned up? " & Finalized)
' Test call to target, it still exists
target.Blah(Nothing, New EventArgs)
MsgBox("Finished.")
End Sub
Public Finalized As Boolean = False
End Module
Friend Class Source
Public Event Blah As EventHandler
Protected Overrides Sub Finalize()
Finalized = True
MyBase.Finalize()
End Sub
Public Sub Fire()
RaiseEvent Blah(Me, New EventArgs)
End Sub
End Class
Friend Class Target
Public Reference As Source
Public Sub Blah(ByVal sender As Object, ByVal e As EventArgs)
MsgBox("Fired!")
End Sub
End Class