In VB.NET using CDO, I'd like to allow multiple threads to share a single
MAPI.Session object. If I declare and instantiate sessions within each
thread, I'm OK (although this negates the efficiency I'm looking to add).
But when I declare, e.g.,
Public objSession As MAPI.Session
I can't access objSession from a worker thread.
Thanks in advance for any advice.
Dave James 6 1920
If I'm not mistaken, the CDO library you're using is marked for single
thread access only. When the library starts, it initializes COM and doesn't
pass the MULTITHREADED flag to CoInitilizeEx. Not necessarily a bug - the
code just doesn't support multi-threaded access.
-Rob Teixeira [MVP]
"Gary Lee" <gl***@earthlink.net> wrote in message
news:z1******************@newsread1.news.pas.earth link.net... In VB.NET using CDO, I'd like to allow multiple threads to share a single MAPI.Session object. If I declare and instantiate sessions within each thread, I'm OK (although this negates the efficiency I'm looking to add). But when I declare, e.g.,
Public objSession As MAPI.Session
I can't access objSession from a worker thread.
Thanks in advance for any advice.
Dave James
Gary,
As Rob suggested, CDO (within .NET) is bound to an STA thread, which means
that it can not be used with an MTA thread (it throws an exception if you
try).
I recently came across the following http://g8.cx/mapi/ "Extended MAPI with
C#", which may allow you to use multiple threads (I have not yet tried the
above library).
Hope this helps
Jay
"Gary Lee" <gl***@earthlink.net> wrote in message
news:z1******************@newsread1.news.pas.earth link.net... In VB.NET using CDO, I'd like to allow multiple threads to share a single MAPI.Session object. If I declare and instantiate sessions within each thread, I'm OK (although this negates the efficiency I'm looking to add). But when I declare, e.g.,
Public objSession As MAPI.Session
I can't access objSession from a worker thread.
Thanks in advance for any advice.
Dave James
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.
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:eW*************@TK2MSFTNGP11.phx.gbl... Gary, As Rob suggested, CDO (within .NET) is bound to an STA thread, which means that it can not be used with an MTA thread (it throws an exception if you try).
I recently came across the following http://g8.cx/mapi/ "Extended MAPI
with C#", which may allow you to use multiple threads (I have not yet tried the above library).
Hope this helps Jay
"Gary Lee" <gl***@earthlink.net> wrote in message news:z1******************@newsread1.news.pas.earth link.net... In VB.NET using CDO, I'd like to allow multiple threads to share a
single MAPI.Session object. If I declare and instantiate sessions within each thread, I'm OK (although this negates the efficiency I'm looking to
add). But when I declare, e.g.,
Public objSession As MAPI.Session
I can't access objSession from a worker thread.
Thanks in advance for any advice.
Dave James
Hi Gary,
"Gary Lee" <gl***@earthlink.net> wrote in message
news:Go****************@newsread2.news.pas.earthli nk.net... 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
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message news:eW*************@TK2MSFTNGP11.phx.gbl... Gary, As Rob suggested, CDO (within .NET) is bound to an STA thread, which
means that it can not be used with an MTA thread (it throws an exception if
you try).
I recently came across the following http://g8.cx/mapi/ "Extended MAPI with C#", which may allow you to use multiple threads (I have not yet tried
the above library).
Hope this helps Jay
"Gary Lee" <gl***@earthlink.net> wrote in message news:z1******************@newsread1.news.pas.earth link.net... In VB.NET using CDO, I'd like to allow multiple threads to share a single MAPI.Session object. If I declare and instantiate sessions within
each thread, I'm OK (although this negates the efficiency I'm looking to add). But when I declare, e.g.,
Public objSession As MAPI.Session
I can't access objSession from a worker thread.
Thanks in advance for any advice.
Dave James
Sven, I think the explanations for the errors you got might be a bit inaccurate:
I'm not certain I've seen a totally accurate explanation yet ;-)
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
Agreed setting the ApartmentState of a Thread is how you set MTA or STA.
However my understanding is MAPI (CDO) requires a call to MapiInitialize in
addition to CoInitialize. However my limited experimentation & Rob's
comments suggests that MapiInitialize is called with STA only. Hence
MAPI.Session then throws an exception, as it is attempting to call
MapiInitilize with parameters with are incompatible with the previously set
ApartmentState...
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
I suspect this will appear to work, I'm concerned what is really happening
(no call to CoInitialize or MapiInitialize)...
Hope this helps
Jay
"Sven Carstensen" <Cv*************@moc.tfg> wrote in message
news:Od**************@TK2MSFTNGP11.phx.gbl... Hi Gary,
"Gary Lee" <gl***@earthlink.net> wrote in message news:Go****************@newsread2.news.pas.earthli nk.net... 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
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in
message news:eW*************@TK2MSFTNGP11.phx.gbl... Gary, As Rob suggested, CDO (within .NET) is bound to an STA thread, which
means that it can not be used with an MTA thread (it throws an exception if you try).
I recently came across the following http://g8.cx/mapi/ "Extended MAPI
with C#", which may allow you to use multiple threads (I have not yet tried the above library).
Hope this helps Jay
"Gary Lee" <gl***@earthlink.net> wrote in message news:z1******************@newsread1.news.pas.earth link.net... > In VB.NET using CDO, I'd like to allow multiple threads to share a single > MAPI.Session object. If I declare and instantiate sessions within each > thread, I'm OK (although this negates the efficiency I'm looking to add). > But when I declare, e.g., > > Public objSession As MAPI.Session > > I can't access objSession from a worker thread. > > Thanks in advance for any advice. > > Dave James > >
Hi Jay,
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:e3**************@TK2MSFTNGP12.phx.gbl... Sven, I think the explanations for the errors you got might be a bit
inaccurate: I'm not certain I've seen a totally accurate explanation yet ;-)
one could get the fealing that MS would like to forget about CDO 1.21 all
together ;-)
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 Agreed setting the ApartmentState of a Thread is how you set MTA or STA.
However my understanding is MAPI (CDO) requires a call to MapiInitialize
in addition to CoInitialize. However my limited experimentation & Rob's comments suggests that MapiInitialize is called with STA only. Hence MAPI.Session then throws an exception, as it is attempting to call MapiInitilize with parameters with are incompatible with the previously
set ApartmentState...
So true: I forgot MAPIInitialize - one would have to call it with the
MAPI_NO_COINIT flag to get it working in an MTA thread.
When oh when will we get a good replacment for CDO/ExMAPI with its client
side notifications and message file format.
Does WebDAV qualify as a candidate for saving messages to files? I like
ExMapi when it comes to its internal knowledge to ignore read only or
computed properties when I use OpenIMsgOnIStg to copy a message completely
to a file based storage.
<snip>
Bye,
SvenC This discussion thread is closed Replies have been disabled for this discussion. Similar topics
2 posts
views
Thread by Bonj |
last post: by
|
1 post
views
Thread by .NET Follower |
last post: by
|
3 posts
views
Thread by CharlieHoo |
last post: by
|
2 posts
views
Thread by jeff_carver |
last post: by
|
7 posts
views
Thread by Kejpa |
last post: by
|
5 posts
views
Thread by Joe |
last post: by
|
3 posts
views
Thread by Sako |
last post: by
|
3 posts
views
Thread by panic |
last post: by
| | | | | | | | | | | |