Visual Basic Development Bookmark and Share   
 Home > 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

HelloAll,

Using Visual Basic 2005Power 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 formwith 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 anyoneknow how to resolve this memory issue?

Regards,

Ben Ellis

DragonWolfZ  Thursday, July 03, 2008 3:38 PM

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.
Riquel_Dong  Thursday, November 05, 2009 6:16 AM
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.
Riquel_Dong  Monday, July 07, 2008 12:19 PM

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?

DragonWolfZ  Thursday, July 17, 2008 3:06 PM
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.
Riquel_Dong  Wednesday, July 30, 2008 3:44 AM

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.
Riquel_Dong  Thursday, November 05, 2009 6:16 AM

You can use google to search for other answers

Custom Search

More Threads

• What tools/scripts are available to automate migration?
• Can I use the Interop Forms Toolkit with VS 2008?
• Passing hDC to unmanaged DLL
• Interop basic question help needed
• calling vb.net class library from vb 6.0
• Referencing a worksheet
• VB6 migration to .net
• call function in C++ having structure pointer using Interop from VB.NET
• using vb .net dll in vb
• Visual Basic Upgrade Wizard Run-Time Error '0'