PRB: Managed Object Is Not Garbage Collected When the Managed Object Handles an Event for an Unmanaged (COM) Object (815120)



The information in this article applies to:

  • Microsoft .NET Framework 1.1
  • Microsoft .NET Framework 1.0

SYMPTOMS

When a managed object contains a reference to an unmanaged (COM) object, and an event handler is added to the managed object to handle the event that is raised by the unmanaged object, the managed object is not garbage collected.

WORKAROUND

To work around the problem, follow these steps:
  1. Implement the IDisposable interface in the managed class.
  2. In the Dispose method, write code to free all the components. Set the oVB6 object to Nothing. Suppress the Finalize method.
  3. Call the Dispose method of the managed object before you set the managed object to Nothing.
  4. Follow steps 1 through 6 in the "Create a Microsoft Visual Basic .NET Console Application to Reproduce the Behavior" section. Replace the code in step 7 with the following code:
    Module Module1
    
        Sub Main()
            Dim c1 As Class1 = New Class1
            Dim wr As System.WeakReference = New WeakReference(c1)
            c1.Dispose()
            c1 = Nothing
    
            GC.Collect()
            GC.WaitForPendingFinalizers()
    
            Console.WriteLine("Is object alive: " & wr.IsAlive)
            Console.ReadLine()
    
        End Sub
    
    End Module
    
    Public Class Class1
        Implements IDisposable
        Private oVB6 As Project1.Class1Class
    
        Public Sub New()
            oVB6 = New Project1.Class1Class
            AddHandler oVB6.MyEvent, AddressOf Me.OnMyEvent
        End Sub
    
        Sub OnMyEvent()
            '
        End Sub
    
        Public Sub Dispose() Implements System.IDisposable.Dispose
            oVB6 = Nothing
            GC.Collect()
            GC.WaitForPendingFinalizers()
            GC.SuppressFinalize(Me)
        End Sub
    
        Protected Overrides Sub Finalize()
            MyBase.Finalize()
        End Sub
    
    End Class
  5. Run the application with the workaround. You may notice that the object is now garbage collected successfully. When you run the code sample that is mentioned in the "More Information" section, you receive the following error message in the Console window:
    "Is object alive: False"

STATUS

This behavior is by design.

MORE INFORMATION

Steps to Reproduce the Behavior

Create and Register a COM Component

  1. Start Microsoft Visual Basic 6.0.
  2. On the File menu, click New Project.
  3. In the New Project dialog box, click ActiveX DLL, and then click OK. By default, Class1 is created.
  4. In the Code window of Class1, add the following code:
    Public Event MyEvent()
    
    Public Sub FireEvent()
        RaiseEvent MyEvent
    End Sub
  5. On the File menu, click Make Project1.dll.
  6. In the Make Project dialog box, click OK. Project1.dll is created.

Create a Microsoft Visual Basic .NET Console Application to Reproduce the Behavior

  1. Start Microsoft Visual Studio .NET.
  2. On the File menu, point to New, and then click Project.
  3. Click Visual Basic Projects under Project Types, and then click Console Application under Templates. By default, Module1 is created.
  4. On the Project menu, click Add Reference.
  5. On the COM tab, click Browse to locate Project1.dll that you created earlier in Visual Basic 6.0.
  6. Click OK.
  7. Replace the existing code in the code window with the following code:
    Module Module1
    
        Sub Main()
            Dim c1 As Class1 = New Class1
            Dim wr As System.WeakReference = New WeakReference(c1)
    
            c1 = Nothing
    
            GC.Collect()
            GC.WaitForPendingFinalizers()
    
            Console.WriteLine("Is object alive: " & wr.IsAlive)
            Console.ReadLine()
    
        End Sub
    
    End Module
    
    Public Class Class1
        Private oVB6 As Project1.Class1Class
    
        Public Sub New()
            oVB6 = New Project1.Class1Class
            AddHandler oVB6.MyEvent, AddressOf Me.OnMyEvent
        End Sub
    
        Sub OnMyEvent()
            '
        End Sub
    
    End Class
  8. On the Build menu, click Build Solution.
  9. On the Debug menu, click Start to run the application. You receive the following error message in the Console window:
    "Is object alive: True"
    This confirms that the object is not garbage collected.

REFERENCES

For more information about automatic memory management, visit the following Microsoft Developer Network (MSDN) Web site:

Modification Type:MinorLast Reviewed:7/18/2003
Keywords:kbDLL kbConsole kbGarbageCollect dtssb kbCOMInterop kbprb KB815120 kbAudDeveloper