I've created a .Net component that has a COM interface. This interface contains events.
I've also got a VB6 client that connects to this component. It recieves the events using the VB6 WithEvents "mechanism".
Setting the WithEvents variable in VB6 to nothing doesn't make the events stop fireing.
Looking deeper into the problem I see that the IConnectionPoint->UnAdvise call that the VB6 client makes when setting the WithEvents variable to nothing fails with error code 0x80040200. The problem gets worse if I set the WithEvents variable to a different object, since the first object still fires events, even if I have no reference to it anymore.
I get the same result using VB.Net as C# to create the component.
Is this a bug in the CCW/Interop stuff
Source below:
VB.NET
<Microsoft.VisualBasic.ComClass()> Public Class DET
Private _t As System.Threading.Timer = Nothing
Public Event TestEvent(ByVal Info As String)
Public Sub New()
_t = New System.Threading.Timer(AddressOf tcb)
_t.Change(5000, 5000)
End Sub
<System.Runtime.InteropServices.ComVisible( False)> Private Sub tcb(ByVal sender As Object)
RaiseEvent TestEvent("Timer " + DateTime.Now.ToString())
End Sub
Public Sub TestMet(ByVal Info As String)
RaiseEvent TestEvent(Info)
End Sub
End Class
C#
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace DisconnectEventTest
{
public delegate void TestEventEventHandler(string Info);
[ ComVisible(true)]
[ Guid(DET.InterfaceId)]
public interface IDET
{
void TestMet(string Info);
}
[ ComVisible(true)]
[ Guid(DET.EventsId)]
[ InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface IDETEvents
{
void TestEvent(string Info);
}
[ Guid(DET.ClassId)]
[ ClassInterface(ClassInterfaceType.None)]
[ ComSourceInterfaces(typeof(IDETEvents))]
[ ComVisible(true)]
public class DET : MarshalByRefObject, IDET
{
internal const string ClassId = "11232094-ABC8-40dc-A9E5-70D87103E8D1";
internal const string InterfaceId = "12345452-28C1-429f-8CEA-86DF341E07B5";
internal const string EventsId = "7227632D-83DC-473e-8DA6-03FE71E62249";
public event TestEventEventHandler TestEvent;
private System.Threading.Timer _t = null;
public DET ()
{
_t = new System.Threading.Timer(tcb);
_t.Change(5000,5000);
}
private void tcb(object sender)
{
TestEvent.Invoke( "Timer " + DateTime.Now.ToString());
}
public override object InitializeLifetimeService()
{ return null; }
public void TestMet(string Info)
{
TestEvent.Invoke (Info);
}
}
}
VB6 Client
Option Explicit
Private WithEvents m_DET As DisconnectEventTest.DET
Private Sub Command4_Click() Set m_DET = New DisconnectEventTest.DET End Sub
Private Sub Command1_Click() m_DET.TestMet Now End Sub
Private Sub Command2_Click() Set m_DET = m_DET '<- Makes event fire multiple times, one for each execution (if m_DET isn't nothing, of cause) End Sub
Private Sub Command3_Click() Set m_DET = Nothing ' <- Doesn't make events stop fireing End Sub
Private Sub m_DET_TestEvent(ByVal Info As String) MsgBox Info End Sub
.NET Development4
|