Visual Basic > Visual Basic Forums > Visual Basic Interop and Upgrade > User Control doesn't terminate when .NET Component is inside
Ask a questionAsk a question
 

AnswerUser Control doesn't terminate when .NET Component is inside

  • Thursday, July 03, 2008 3:38 PMDragonWolfZ Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    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

            

Answers

  • Thursday, November 05, 2009 6:16 AMRiquel_DongModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer

    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.

All Replies

  • Monday, July 07, 2008 12:19 PMRiquel_DongModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    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.
  • Thursday, July 17, 2008 3:06 PMDragonWolfZ Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    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?

  • Wednesday, July 30, 2008 3:44 AMRiquel_DongModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    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.
  • Thursday, November 05, 2009 6:16 AMRiquel_DongModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer

    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.