Microsoft KB Archive/827418

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

Article ID: 827418

Article Last Modified on 4/19/2007

-

APPLIES TO


 * Microsoft .NET Framework 1.1
 * Microsoft .NET Framework 1.0
 * Microsoft Visual Basic 6.0 Enterprise Edition
 * Microsoft Visual Basic 6.0 Professional Edition

-



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 &quot;More Information&quot; section of this article, and then follow these steps:   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 (&quot;Disconnected from the event source&quot;)  On the Run menu, click Start. Click Command1.



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



Steps to Reproduce the Behavior
 Start Microsoft Visual Studio .NET. On the File menu, point to New, and then click Project.</li> Click Visual Basic Projects under Project Types, and then click Class Library under Templates.</li> In the Name box, type EventSource, and then click OK. By default, Class1 is created.</li>  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 </li> In Solution Explorer, right-click EventSource, and then click Properties.</li> Expand the Configuration Properties node in the left pane, and then click Build.</li> Click to select the Register for COM Interop check box.</li> In the EventSource Property Pages dialog box, click OK.</li> On the Build menu, click Build Solution.</li> In Microsoft Visual Basic 6.0, create a new Standard EXE project. By default, Form1 is created.</li> On the Project menu, click References.</li> In the References dialog box, click Browse.</li> In the Add Reference dialog box, locate the EventSource project folder on your computer.</li> Click EventSource.tlb in the bin folder, and then click Open.</li> In the References dialog box, click OK.</li> Add a CommandButton control to Form1. By default, Command1 is created.</li> <li> 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 (&quot;Disconnected from the event source&quot;) 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 </li> <li>On the File menu, click Save Project.</li> <li>On the Run menu, click Start.</li> <li>Click Command1. Notice that the application stops responding.</li></ol>

<div class="references_section">