Re: Problem with COM and Threading
spforeman <google@sforeman.com> wrote:
Basically I have a local server (ATL) that accesses hardware for me
and a proxy that allows me to place a control that accesses the
server into an app, I am embedding this control in a VB app.
The local server communicates with some hardware that collects a new
image and then send an event to the proxy to say that a new image is
available. When the proxy receives this event it asks the server for
the image and then tells the control to redraw itself by calling
CComControlBase::FireViewChange(). This causes the proxy's OnDraw to
be called which then displays the image.
Both the server and the proxy are _ATL_FREE_THREADED
When you say "control", do you mean a visual ActiveX control that you
put on VB form? These can't be free-threaded, they must be
apartment-threaded. Windows UI is thread-affine - a window can only be
manipulated from the thread that created it.
The local server on the other hand can happily be free-threaded.
Further investigation shows that the call to OnDraw, resulting because
of FireViewChange(), and the call to OnDraw because of the window
trying to repaint as the mouse moves over it are not synchronised,
even though they appear to occur within the same thread. This
results in the same function (OnDraw) being called multiple times at
the same time from the same thread.
Do you make any COM calls from inside OnDraw? It's a bad idea for a
number of reasons. You have discovered one of them: when making a
cross-apartment COM call, your thread enters a modal message pump that
may dispatch incoming messages and cause reentrancy. Cache the last
image you've received from the server, have OnDraw simply dump it on the
screen without making any COM calls.
--
With best wishes,
Igor Tandetnik
With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925