Hi Gary,
Gary Lee said:
Thanks Rob and Jay for the replies. I'll check out
http://g8.cx/mapi/.
In the meantime, I made things work by creating one session per thread --
not as elegant as I'd like, but it works.
that is in many situations the more elegant solution. Whenever you have
threads own the resources they use you get them decoupled which keeps you
away from synchronization problems.
I think the explanations for the errors you got might be a bit inaccurate:
it is not the COM component CDO which initializes a thread as STA or MTA -
that would not work because you cannot change that setting later on so using
two objects with different apartment models in one thread would result in a
conflict. It is always the client of the COM objects who has to set the
apartment model for each thread it creates. For your main UI thread you can
do this with attributes but for dynamically created threads you will have to
set the ApartmentState of that thread prior to starting it - I guess that
"configures" the call to CoInitialize or CoInitializeEx. If you don't set
that property to STA or MTA COM will not get initialized on that thread. So
any COM call will fail on that thread because of COM not being initialized.
I think you should even be able to use CDO inproc from an MTA thread. This
should result in a proxy object in the MTA thread which uses thread message
queues to communicate with the real CDO object created in an STA object.
Uups: just looked up my CDO apartment registration: it is set up as "Both"
which means - ahhh come on my developers are clever guys you can use me in
STA or MTA I don't care I always work (well this is a "description" in the
registry of how it should be

). So it will even execute directly in the
MTA thread.
JUST A TECHNICAL DEMO, DONT DO THIS IN PRODUCTION CODE: just give it a try:
set the ApartmentState property of your thread to MTA and you should be able
to use a CDO Session created in one of those in all the others. What will
not work is passing an object reference between STA (your main UI thread
e.g.) and MTA. If you want to do that you will need to marshal the object
reference. CoMarshalInterTreadInterfaceInStream and
CoGetInterfaceAndReleaseStream or use the GIT (global interface table).
I strongly don't recommend that with CDO because you can run in all kinds of
problems with CDO as it is not really designed as a multithreaded server
library - I ran into so much issues with it just because I wanted to use an
easy COM component instead of ExMapi in a server app
Bye,
SvenC