Queued components is a great service, no doubt, but it does have a few quirks and pitfalls that I would like to point out.
MSMQ can be installed in two configurations. The first relies on having a Windows 2000 domain server present on the network. The workstation onto which you wish to install MSMQ must be part of that domain. The second installation option is for a Windows Workgroup.
To call queued components across the network securely, queued components require the presence of a Message Queuing Primary Enterprise Controller (PEC) on the network. If you install MSMQ for Workgroup, you have to turn the security knob all the way down (set the authentication level for the queued components application to None and avoid using access control checks). Any cross-machine calls must be unauthenticated. This limitation is serious. For any Enterprise-level worthy application, you need the MSMQ domain server installation.
A client of a queued component can run only on a Windows 2000 machine. There is no apparent reason for this condition, as every Microsoft platform supports MSMQ. What makes it even more awkward is the fact that most portable devices that could benefit from disconnected sessions will not run Windows 2000.[5]
As mentioned before, a queued component
client can pass in as a method parameter an interface pointer to a
COM object, provided that the object supports the
IPersistStream
(so that COM+ can serialize the
object state into a stream).
However, if the object is written in Visual Basic 6, the object must
be initialized before making the call on the recorder interface by
querying it for IPersistStream
and calling one of
the
IPersistStream
methods Init( )
,
InitNew( )
, or Load( )
.
If your client is written in Visual Basic as well, the Visual Basic runtime handles the object initialization automatically for you. If the client application is written in C++, the application must initialize the component explicitly. Requiring the client to know the language used to implement the queued component couples the client to the component, but knowing of a limitation is better than trying to figure out what went wrong.
When a queued component client makes a call, it actually interacts
with a recorder. The recorder has to match as much as possible the
behavior of the real component, including its implementation of
IUnknown::QueryInterface( )
. The recorder bases
everything it does on the component-type library. It is common for a
component to support multiple interfaces derived from
IDispatch
. If that is the case, what interface
should the recorder return to the client when it is queried for
IDispatch( )
?
The recorder uses the following algorithm to provide the right
IDispatch( )
:
If the component default interface inherits from
IDispatch
, the default interface is returned.
If no interface is marked as default, but only one interface inherits
from IDispatch
, that interface is returned.
If no interface is marked as default and multiple interfaces inherit
from IDispatch
, the recorder returns
E_NOINTERFACE
.
The obvious recommendation is to always mark one of your component
IDispatch
-derived interfaces as the default
interface.
When an application hosts queued components, COM+ must activate a listener for queued calls sent to its queue whenever the application is launched. If you package queued and nonqueued components in a single application, the application might service clients of nonqueued components when a queued call arrives. This situation may be a cause for concern if the queued component makes a lot of CPU-intensive calculations or requires other expensive resources. These characteristics may be the reasons you made that component queued—so that your component will not be in the way of other components and will do the expensive processing at times when the system load is low.
When deciding on component allocation to applications, make sure that you really want queued components to start when a nonqueued component executes. If you would like to control the queued components’ execution time, package the queued components into a separate COM+ application and explicitly start it up when you deem it fit.
[5] I can only say that I find this situation very strange, and I hope that Microsoft will amend this predicament soon.