I have a
COM-visible VB.NET component (made with VS2005) which raises events to its COM
clients, and the act of raising an event seems to cause an exception in some
circumstances. The circumstances seem to be where a COM client object has
registered for (or indeed received) events from the VB.NET object and then been
destroyed; The next time the VB.NET object raises an event it causes an
exception, as follows:
If the client object has received one or more events before it was
destroyed:
Error Number: 0x80010007
Error Source: mscorlib
Error Description: The callee (server [not server application]) is not
available and disappeared; all connections are invalid. The call may have
executed. (Exception from HRESULT: 0x80010007 (RPC_E_SERVER_DIED))
If the client object merely registered for events but didn't receive any
before it was destroyed:
Error Number: 0x80131603
Error Source: mscorlib
Error Description: Object does not match target type
I observed this behaviour with a COM client written in VB6, and have included
(below) some simplified source code for both client and server to demonstrate
the problem. But before you all start shouting that VB6 questions are not
welcome here, I would point out that I have also included some COM client code
in C++ (see below). Although I didn't observe the same symptoms with the C++
client, I did get some strange behaviour which might serve as further evidence
that the problem is in the framework and not in VB6:
The C++ client's Main function creates a COM client object (also defined in
native C++) and calls a method of that object which:
- connects to the outgoing interface of the VB.NET object;
- receives an event; and
- disconnects
and then it releases the COM client object. That call to
Release() should cause the COM client object to be deleted, since there are no
other references to it (and when I run the same client code with a native COM
server in place of the VB.NET object it does in fact delete it). But in
this case, with the VB.NET object, the call to Release returns 2 (instead of
zero), indicating that something else is still holding a reference or two to
it. And if I allow the code to force the client object to be deleted, by
repeatedly calling Release() until it returns zero, I later get two instances
of the following when the application terminates:
First-chance exception at 0x79e8db36 (mscorwks.dll)
in ConsoleComClient.exe: 0xC0000005: Access violation reading location
0x[address varies]
Again, I don't get
any of this strange behaviour when I run the same client code against an
unmanaged COM server.
It seems to me that this is not inconsistent with the behaviour I observed with
the VB6 client (in the case where the client object has received events before
it was destroyed), even though the symptoms are different. The VB6 client's
behaviour suggests to me that the framework is not releasing its references to
the client's sink when the client calls IConnectionPoint->Unadvise(), and
may even be trying to call the relevant event-method of the client's sink even
after it has called Unadvise.
So I would be interested to hear from anyone who has seen this problem before,
or from anyone who knows whether there is a fix for it.
Many thanks,
Chris Pyman
(source code follows ... apologies for the long post)

VB.NET raising events to COM clients