Visual Basic >
Visual Basic Forums
>
Visual Basic Interop and Upgrade
>
User Control doesn't terminate when .NET Component is inside
User Control doesn't terminate when .NET Component is inside
- Hello All,
Using Visual Basic 2005 Power Packs - Interop Forms Toolkit 2.0,
I create the VB6 Interop UserControl project, then drag-and-drop a button onto the control.
I then create a VB6 app that contains,
1. A User Control that contains the VB6 Interop user control.
2. A form with buttons that load and unload the user control.
When I unload the user control, the Terminate event never triggers and the memory doesn't clear. This causes a memory leak as I end up creating the control over and over without ever destroying it.
Has anyone else experienced this problem? Or does anyone know how to resolve this memory issue?
Regards,
Ben Ellis
- Changed TypeRiquel_DongModeratorFriday, August 08, 2008 1:22 AMdon't follow up
- Moved byJohnHart_MSFTModeratorThursday, July 03, 2008 9:23 PMmoving to Interop forum for better help
- Changed TypeRiquel_DongModeratorThursday, November 05, 2009 6:17 AM
Answers
Please visit this thread:
http://social.msdn.microsoft.com/Forums/en-US/vbinterop/thread/fec266fb-7a00-4700-9100-2349b772308e
Also have a look at this article about CCW. Although it is related to compact framework, the theory is identical. We can know that the culprit is CCW which is not released here.
http://blogs.msdn.com/netcfteam/archive/2005/07/24/442612.aspx
I think that ActiveX control should have reference to CCW for the underlying .NET Interop control, so .NET GC doesn't collect this .NET object. Finally ActiveX control is alive too.
The key reason is that ActiveX control has the reference to underlying .NET Interop control. Because there is the reference to .NET control, GC can't collect .NET Interop control. ActiveX control is not released in this situation. Currently I dynamically add .NET Interop control in AxtiveX control(please have a look at the following code snippet). After I remove this .NET control from control collection, the ActiveX terminate event is fired. Also please refer to the following links about Controls property in VB6.
http://msdn.microsoft.com/en-us/library/aa277578(VS.60).aspx
frmInteropControl code
Private Sub Form_Unload(Cancel As Integer)
Me.UCInteropControl1.cleanup
End Sub
ActiveX control code
Option Explicit
Dim Cmd1 As InteropTextBox1
Public MsgBoxOnTerminate As Boolean
Dim ctl As Control
Private Sub UserControl_Initialize()
Set Cmd1 = Controls.Add("InteropTextBox1.InteropTextBox1", "Cmd1")
Cmd1.Width = 2000
Cmd1.Top = 500
Cmd1.Left = 500
Cmd1.Visible = True
End Sub
Private Sub UserControl_Terminate()
If MsgBoxOnTerminate Then
MsgBox "UserControl_Terminate", vbInformation, UserControl.Name
End If
End Sub
Public Sub cleanup()
Controls.Remove "Cmd1"
Set Cmd1 = Nothing
End Sub
If you have any further issues, feel free to tell us.
Best regards,
Riquel
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.- Proposed As Answer byRiquel_DongModeratorThursday, November 05, 2009 6:17 AM
- Marked As Answer byRiquel_DongModeratorThursday, November 05, 2009 8:55 AM
All Replies
- Hi Ben,
Read COM Callable Wrapper for your reference. In "Object Lifetime" section: Unlike the .NET client it wraps, the CCW is reference-counted in traditional COM fashion. When the reference count on the CCW reaches zero, the wrapper releases its reference on the managed object. A managed object with no remaining references is collected during the next garbage-collection cycle.
We don't see how you cleanup the object. Commonly it is the best option to call “=Nothing” on the objects. This will release the reference.
Best regards,
Riquel
Please remember to mark the replies as answers if they help and unmark them if they provide no help.- Unmarked As Answer byRiquel_DongModeratorWednesday, July 30, 2008 1:30 AM
- Marked As Answer byRiquel_DongModeratorWednesday, July 09, 2008 6:43 AM
- Edited byRiquel_DongModeratorTuesday, July 08, 2008 11:48 AMmodify the content
I set all the .NET controls to Nothing in my VB application, but the memory continues to increase until it reaches about 1.5 gig before I start getting OutOfMemoryExceptions.
I'll try forcing the GC.Collect() but I thought this should have executed long before I run out of memory.
Do I need to explicitly remove any event handling references as well?- Hi Ben,
Don't see your code snippet about usercontrol and how you create the control and release the reference. It is hard to know this issue. Please supply the more information.
For .Net applications, if we create a large number of objects and keep references to them (like adding event handlers to a WinForm control repeatedly but never removing them), garbage collection will not be able to reclaim them. Hence memory leak occurs. Could you tell us how you add event handler here?
Best regards,
Riquel
Please remember to mark the replies as answers if they help and unmark them if they provide no help.- Edited byRiquel_DongModeratorWednesday, July 30, 2008 12:42 PMmodify the content
Please visit this thread:
http://social.msdn.microsoft.com/Forums/en-US/vbinterop/thread/fec266fb-7a00-4700-9100-2349b772308e
Also have a look at this article about CCW. Although it is related to compact framework, the theory is identical. We can know that the culprit is CCW which is not released here.
http://blogs.msdn.com/netcfteam/archive/2005/07/24/442612.aspx
I think that ActiveX control should have reference to CCW for the underlying .NET Interop control, so .NET GC doesn't collect this .NET object. Finally ActiveX control is alive too.
The key reason is that ActiveX control has the reference to underlying .NET Interop control. Because there is the reference to .NET control, GC can't collect .NET Interop control. ActiveX control is not released in this situation. Currently I dynamically add .NET Interop control in AxtiveX control(please have a look at the following code snippet). After I remove this .NET control from control collection, the ActiveX terminate event is fired. Also please refer to the following links about Controls property in VB6.
http://msdn.microsoft.com/en-us/library/aa277578(VS.60).aspx
frmInteropControl code
Private Sub Form_Unload(Cancel As Integer)
Me.UCInteropControl1.cleanup
End Sub
ActiveX control code
Option Explicit
Dim Cmd1 As InteropTextBox1
Public MsgBoxOnTerminate As Boolean
Dim ctl As Control
Private Sub UserControl_Initialize()
Set Cmd1 = Controls.Add("InteropTextBox1.InteropTextBox1", "Cmd1")
Cmd1.Width = 2000
Cmd1.Top = 500
Cmd1.Left = 500
Cmd1.Visible = True
End Sub
Private Sub UserControl_Terminate()
If MsgBoxOnTerminate Then
MsgBox "UserControl_Terminate", vbInformation, UserControl.Name
End If
End Sub
Public Sub cleanup()
Controls.Remove "Cmd1"
Set Cmd1 = Nothing
End Sub
If you have any further issues, feel free to tell us.
Best regards,
Riquel
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.- Proposed As Answer byRiquel_DongModeratorThursday, November 05, 2009 6:17 AM
- Marked As Answer byRiquel_DongModeratorThursday, November 05, 2009 8:55 AM


