BUG: A Visual Basic Application Stops Responding While It Disconnects from the Managed Event Source (827418)



The information in this article applies to:

  • Microsoft .NET Framework 1.1
  • Microsoft .NET Framework 1.0
  • Microsoft Visual Basic Enterprise Edition for Windows 6.0
  • Microsoft Visual Basic Professional Edition for Windows 6.0

SYMPTOMS

A Visual Basic application may stop responding if you follow these steps:
  1. You define an event as the connection point to Component Object Model (COM) clients in the .NET Framework component. The .NET Framework component is the event source and raises events.
  2. You create an unmanaged COM client application, such as a Microsoft Visual Basic 6.0 application, to implement the event sink interface.
  3. You create WithEvents variables in the Visual Basic 6.0 application to handle events that are raised by the event source. The WithEvents variables reference the same instance of the managed class.
  4. You try to disconnect the WithEvents variables from the event source.

CAUSE

This problem occurs because Microsoft Visual Basic Virtual Machine 6.0 (MSVBVM60) uses the Next method of the IEnumConnections interface to enumerate current connections to the connectable object (event). In this case, the IEnumeration::Next method does not move the internal pointer to the next element while it closes connections. This creates an infinite loop, and the Visual Basic application stops responding while it disconnects from the event source.

RESOLUTION

To resolve this problem, close connections to the event source in the reverse order of the connection creation. To do so, create the sample that is listed in the "More Information" section of this article, and then follow these steps:
  1. Replace the code in the Command1_Click procedure of Form1 with the following code:
    'Disconnect myButton1, myButton2 from the event source.
    Set myButton2 = Nothing
    Set myButton1 = Nothing
    MsgBox ("Disconnected from the event source")
  2. On the Run menu, click Start.
  3. Click Command1.

STATUS

Microsoft has confirmed that this is a bug in the Microsoft products that are listed at the beginning of this article.

MORE INFORMATION

Steps 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 Class Library under Templates.
  4. In the Name box, type EventSource, and then click OK. By default, Class1 is created.
  5. Replace the existing code in the Class1.vb file with the following code:
    Option Explicit On 
    Option Strict On
    
    Imports System
    Imports System.Runtime.InteropServices
    
    Namespace EventSource
        Public Delegate Sub ClickDelegate(ByVal x As Integer, ByVal y As Integer)
    
        ' Step 1: Define the event sink interface (ButtonEvents) that is to be
        ' implemented by the COM sink.
    
        <InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)> _
        Public Interface ButtonEvents
            Sub Click(ByVal x As Integer, ByVal y As Integer)
        End Interface
    
        ' Step 2: Connect the event sink interface (ButtonEvents) to a class.
        ' This exposes the ButtonEvents interface as a COM event source.
    
        <ComSourceInterfaces(GetType(ButtonEvents))> _
            Public Class Button
            'Step 3: Declare the event that is to be handled.
            Public Event Click As ClickDelegate
    
            Public Sub CauseClickEvent(ByVal x As Integer, ByVal y As Integer)
                'Step 4: Raise the Click event by using the RaiseEvent statement.
                RaiseEvent Click(x, y)
            End Sub
    
        End Class
    End Namespace
    
  6. In Solution Explorer, right-click EventSource, and then click Properties.
  7. Expand the Configuration Properties node in the left pane, and then click Build.
  8. Click to select the Register for COM Interop check box.
  9. In the EventSource Property Pages dialog box, click OK.
  10. On the Build menu, click Build Solution.
  11. In Microsoft Visual Basic 6.0, create a new Standard EXE project. By default, Form1 is created.
  12. On the Project menu, click References.
  13. In the References dialog box, click Browse.
  14. In the Add Reference dialog box, locate the EventSource project folder on your computer.
  15. Click EventSource.tlb in the bin folder, and then click Open.
  16. In the References dialog box, click OK.
  17. Add a CommandButton control to Form1. By default, Command1 is created.
  18. On the View menu, click Code, and then add the following code:
    Option Explicit
    'Use the WithEvents keyword to handle events of EventSource.Button objects.
    Public WithEvents myButton1 As EventSource.Button
    Public WithEvents myButton2 As EventSource.Button
    
    Private Sub Command1_Click()
    'Disconnect myButton1, myButton2 from the event source.
    Set myButton1 = Nothing
    Set myButton2 = Nothing
    MsgBox ("Disconnected from the event source")
    End Sub
    
    Private Sub Form_Load()
    'Set the myButton1 and myButton2 objects to the same instance of EventSource.Button.
    'This connects myButton1 and myButton2 to the event source, that is, the .NET Framework component.
    Set myButton1 = New EventSource.Button
    Set myButton2 = myButton1
    End Sub
    
  19. On the File menu, click Save Project.
  20. On the Run menu, click Start.
  21. Click Command1. Notice that the application stops responding.

REFERENCES

For additional information, click the following article number to view the article in the Microsoft Knowledge Base:

813105 FIX: .NET Framework Implementation of IEnumConnections::Next Causes the Client Application to Stop Responding

For more information, visit the following MSDN, Microsoft Developer Network, Web sites:

Modification Type:MajorLast Reviewed:9/15/2003
Keywords:kbDLL kbEvent kbManaged kbCOMInterop kbbug KB827418 kbAudDeveloper