PC Review
Forums
Newsgroups
Microsoft Outlook
Microsoft Outlook Program Addins
Addin mulithreading
Forums
Newsgroups
Microsoft Outlook
Microsoft Outlook Program Addins
Addin mulithreading
![]() |
Addin mulithreading |
|
|
Thread Tools | Rate Thread |
|
|
#1 |
|
Guest
Posts: n/a
|
Hello,
I am thinking of spawning a thread of processing the MAPIFolder selected everytime when the BeforeFolderSwitch was trigger. I overheard that Outlook VBA/OOM is a single threaded, is it true? And even if it is single threaded, can I do a multhreading programming? Any precautions that I need to look into or anyone has done it in the past. Reason I want to do this is my addin need to response to the network, sometimes there are some lagging occur in the network. By the way, I am using Redemption and extended MAPI too. Do these have issue on the multi-threading? thanks. |
|
|
|
#2 |
|
Guest
Posts: n/a
|
All Outlook objects are apartment threaded, so all the calls to the OOM
objects from a secondary thread will be marshlled to the main Outlook thread. You can of course do non-OOM processing on the secondary thread. Extended MAPI and Redemption are thread-safe, but your mileage may vary of course. Dmitry Streblechenko (MVP) http://www.dimastr.com/ OutlookSpy - Outlook, CDO and MAPI Developer Tool "Semut" <ant_yio@hotmail.com> wrote in message news:OPRGVlOMFHA.2704@TK2MSFTNGP15.phx.gbl... > Hello, > > I am thinking of spawning a thread of processing the MAPIFolder > selected everytime when the BeforeFolderSwitch was trigger. I overheard > that Outlook VBA/OOM is a single threaded, is it true? And even if it is > single threaded, can I do a multhreading programming? Any precautions that > I need to look into or anyone has done it in the past. Reason I want to do > this is my addin need to response to the network, sometimes there are some > lagging occur in the network. > > By the way, I am using Redemption and extended MAPI too. Do these have > issue on the multi-threading? > > thanks. > > > |
|
|
|
#3 |
|
Guest
Posts: n/a
|
Ok, supposing I spawn my secondary thread and it will connect to network and
update the MAPIFolder of the Outlook using OOM. In my main thread, the Outlook itself, I will probably do some work like adding items to the MAPIfolder manually. (probably the same MAPIFolder points to as the MAPIFolder spawned in the thread.) Do I need to call ::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);and ::CoUninitialize();in my secondary thread so that it will create two standard single threaded apartments?(or it is not necessary?)How to do about?thanks "Dmitry Streblechenko" <dmitry@dimastr.com> wrote in message news:O%237ZVKQMFHA.3420@tk2msftngp13.phx.gbl... > All Outlook objects are apartment threaded, so all the calls to the OOM > objects from a secondary thread will be marshlled to the main Outlook > thread. > You can of course do non-OOM processing on the secondary thread. > Extended MAPI and Redemption are thread-safe, but your mileage may vary of > course. > > Dmitry Streblechenko (MVP) > http://www.dimastr.com/ > OutlookSpy - Outlook, CDO > and MAPI Developer Tool > > "Semut" <ant_yio@hotmail.com> wrote in message > news:OPRGVlOMFHA.2704@TK2MSFTNGP15.phx.gbl... >> Hello, >> >> I am thinking of spawning a thread of processing the MAPIFolder >> selected everytime when the BeforeFolderSwitch was trigger. I overheard >> that Outlook VBA/OOM is a single threaded, is it true? And even if it is >> single threaded, can I do a multhreading programming? Any precautions >> that I need to look into or anyone has done it in the past. Reason I want >> to do this is my addin need to response to the network, sometimes there >> are some lagging occur in the network. >> >> By the way, I am using Redemption and extended MAPI too. Do these have >> issue on the multi-threading? >> >> thanks. >> >> >> > > |
|
|
|
#4 |
|
Guest
Posts: n/a
|
You must call CoInitializeEx (or CoInitialize) in your secondary threads if
you are using COM on that thread. Dmitry Streblechenko (MVP) http://www.dimastr.com/ OutlookSpy - Outlook, CDO and MAPI Developer Tool "Semut" <ant_yio@hotmail.com> wrote in message news:eB54cqRMFHA.1948@TK2MSFTNGP14.phx.gbl... > Ok, supposing I spawn my secondary thread and it will connect to network > and update the MAPIFolder of the Outlook using OOM. In my main thread, the > Outlook itself, I will probably do some work like adding items to the > MAPIfolder manually. (probably the same MAPIFolder points to as the > MAPIFolder spawned in the thread.) > > Do I need to call > > ::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);and ::CoUninitialize();in > my secondary thread so that it will create two standard single threaded > apartments?(or it is not necessary?)How to do about?thanks > > "Dmitry Streblechenko" <dmitry@dimastr.com> wrote in message > news:O%237ZVKQMFHA.3420@tk2msftngp13.phx.gbl... >> All Outlook objects are apartment threaded, so all the calls to the OOM >> objects from a secondary thread will be marshlled to the main Outlook >> thread. >> You can of course do non-OOM processing on the secondary thread. >> Extended MAPI and Redemption are thread-safe, but your mileage may vary >> of course. >> >> Dmitry Streblechenko (MVP) >> http://www.dimastr.com/ >> OutlookSpy - Outlook, CDO >> and MAPI Developer Tool >> >> "Semut" <ant_yio@hotmail.com> wrote in message >> news:OPRGVlOMFHA.2704@TK2MSFTNGP15.phx.gbl... >>> Hello, >>> >>> I am thinking of spawning a thread of processing the MAPIFolder >>> selected everytime when the BeforeFolderSwitch was trigger. I overheard >>> that Outlook VBA/OOM is a single threaded, is it true? And even if it is >>> single threaded, can I do a multhreading programming? Any precautions >>> that I need to look into or anyone has done it in the past. Reason I >>> want to do this is my addin need to response to the network, sometimes >>> there are some lagging occur in the network. >>> >>> By the way, I am using Redemption and extended MAPI too. Do these have >>> issue on the multi-threading? >>> >>> thanks. >>> >>> >>> >> >> > > |
|
|
|
#5 |
|
Guest
Posts: n/a
|
"Semut" wrote:
> Ok, supposing I spawn my secondary thread and it will connect to network and > update the MAPIFolder of the Outlook using OOM. In my main thread, the > Outlook itself, I will probably do some work like adding items to the > MAPIfolder manually. (probably the same MAPIFolder points to as the > MAPIFolder spawned in the thread.) > > Do I need to call > > ::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);and ::CoUninitialize();in > my secondary thread so that it will create two standard single threaded > apartments?(or it is not necessary?)How to do about?thanks Of course you need CoInitialize but single threaded or multi threaded depends what else compomets do you plan to use from that thread. So your thread will work independently to main Outlook thread. But when you call some OOM methods your thread will stop and wait while system switch thread context to the main thread and call requested method in the context of the main thread. After returning from OOM the call you thread againg works on its own. The only you need is to obtain pointers to the OOM objects in the proper way. CoCreateInstance will do. If it is existing object you shoud marshal it manualy between main thread an the worker thread. > > "Dmitry Streblechenko" <dmitry@dimastr.com> wrote in message > news:O%237ZVKQMFHA.3420@tk2msftngp13.phx.gbl... > > All Outlook objects are apartment threaded, so all the calls to the OOM > > objects from a secondary thread will be marshlled to the main Outlook > > thread. > > You can of course do non-OOM processing on the secondary thread. > > Extended MAPI and Redemption are thread-safe, but your mileage may vary of > > course. > > > > Dmitry Streblechenko (MVP) > > http://www.dimastr.com/ > > OutlookSpy - Outlook, CDO > > and MAPI Developer Tool > > > > "Semut" <ant_yio@hotmail.com> wrote in message > > news:OPRGVlOMFHA.2704@TK2MSFTNGP15.phx.gbl... > >> Hello, > >> > >> I am thinking of spawning a thread of processing the MAPIFolder > >> selected everytime when the BeforeFolderSwitch was trigger. I overheard > >> that Outlook VBA/OOM is a single threaded, is it true? And even if it is > >> single threaded, can I do a multhreading programming? Any precautions > >> that I need to look into or anyone has done it in the past. Reason I want > >> to do this is my addin need to response to the network, sometimes there > >> are some lagging occur in the network. > >> > >> By the way, I am using Redemption and extended MAPI too. Do these have > >> issue on the multi-threading? > >> > >> thanks. > >> > >> > >> > > > > > > > |
|
|
|
#6 |
|
Guest
Posts: n/a
|
I will be utilizing the global variable of Outlook::_Application in my
worker thread. Then, through the Application object, I obtain the Outlook::_Namespace variable and then the MAPIFolder. This is to avoid the security alert by Outlook. Will it be fine that way? Also, I will be passing a MAPIFolder to my worker thread function by myCall( spMAPIFolder.Detach()); so that my worker thread will release the ref count it self. It this ok? Ok, my worker thread function do call. ::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); .... ::CoUninitialize(); Previously, without calling these, the functions in the thread, especially those CoCreateInstance will fail. > The only you need is to obtain pointers to the OOM objects in the proper > way. > > CoCreateInstance will do. > If it is existing object you shoud marshal it manualy between main thread > an > the worker thread. Can you show a code snippet for that? Supposingly, I need to pass a MAPIFolder to my worker thread. How do I marshal or use the CoCreateInstance. (I am using Redemption and Extendded MAPI also, so you can show in Redemption also no problem, not bound to be OOM only. ) At the moment, the MAPIFolder smart pointer (CComPtr < Outlook :: MAPIFolder > ) give me problem when it try to Release the ref count when it goes out of the scope. In a non multi-threaded environment, this call was fine but when I switch to MT. The program will complain for error about the MAPIfolder. |
|
|
|
#7 |
|
Guest
Posts: n/a
|
At the moment, I pass a MAPIFolder to my thread function like
callMyThreadFunc(spMAPIFolder.Detach()); The spMAPIFolder will get release in the thread function itself cause I pass the ownership to a LPDISPATCH in the thread function. So, the reading of the MAPIFolder have no problem. The problem is when I want to add item. The smart pointer will complaint exception (0x0eedfade). It is something to do with the MAPIFolder smart pointer when it tries to release a ref count which has been released. Previously, not in Multi Threaded environment, there wasn;t any of this problems. By the way, in the my thread func. I have ::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); ...... ..... ...... ::CoUninitialize(); > The only you need is to obtain pointers to the OOM objects in the proper > way. > > CoCreateInstance will do. > If it is existing object you shoud marshal it manualy between main thread > an > the worker thread. Can you show a code snippet for that. Say, I need to pass a MAPIFolder to my thread function. And, the MAPIFolder would problably need to be updated. thanks |
|
|
|
#8 |
|
Guest
Posts: n/a
|
See some snipped
that is for Application pointer. ALL OOM pointers should be marshalled like this. MAPIFolder is thread safe so it can be easily passed between threads. That peace of code from D.Box's book "Essential COM". I've modified it a bit. HRESULT WritePtr(Outlook::_Application *pApplication, HGLOBAL& rhglobal) { IStream *pStm = 0; Çhglobal = 0; // alloc and wrap block of memory HRESULT hr = CreateStreamOnHGlobal(0, FALSE, &pStm); if (SUCCEEDED(hr)) { // write marshaled object reference to memory hr = CoMarshalInterface(pStm, __uuidof(Outlook::_Application), pApplication, MSHCTX_INPROC, 0, MSHLFLAGS_NORMAL); // extract handle to underlying memory if (SUCCEEDED(hr)) hr = GetHGlobalFromStream(pStm, &rhglobal); pStm->Release(); } return hr; } HRESULT ReadPtr(HGLOBAL hglobal, Outlook::_Application* &pApplication) { IStream *pStm = NULL; pApplication = NULL; // wrap block of existing memory passed on input HRESULT hr = CreateStreamOnHGlobal(hglobal, FALSE, &pStm); if (SUCCEEDED(hr)) { // get a pointer to the object that is legal in this apt. hr = CoUnmarshalInterface(pStm, __uuidof(Outlook::_Application), (void**)&pApplication); pStm->Release(); } return hr; } So you write pointer in the main thread and obtain HGLOBAL handle pass that handle to the worker thread. In the thread call ReadPtr and obtain marshalled pointer. use GlobalFree to free HGLOBAL handle. WBR Henry "Semut" <ant_yio@hotmail.com> wrote in message news:OXQXxq0MFHA.2736@TK2MSFTNGP09.phx.gbl... > I will be utilizing the global variable of Outlook::_Application in my > worker thread. > > Then, through the Application object, I obtain the Outlook::_Namespace > variable and then the MAPIFolder. > > This is to avoid the security alert by Outlook. > > Will it be fine that way? > > Also, I will be passing a MAPIFolder to my worker thread function by > > myCall( spMAPIFolder.Detach()); > > so that my worker thread will release the ref count it self. It this ok? > > > Ok, my worker thread function do call. > > ::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); > > ... > > ::CoUninitialize(); > > Previously, without calling these, the functions in the thread, especially > those CoCreateInstance will fail. > > > > The only you need is to obtain pointers to the OOM objects in the proper > > way. > > > > CoCreateInstance will do. > > If it is existing object you shoud marshal it manualy between main thread > > an > > the worker thread. > > Can you show a code snippet for that? > Supposingly, I need to pass a MAPIFolder to my worker thread. How do I > marshal or use the CoCreateInstance. (I am using Redemption and Extendded > MAPI also, so you can show in Redemption also no problem, not bound to be > OOM only. ) > > At the moment, the MAPIFolder smart pointer (CComPtr < Outlook :: MAPIFolder > > ) give me problem when it try to Release the ref count when it goes out > of the scope. In a non multi-threaded environment, this call was fine but > when I switch to MT. The program will complain for error about the > MAPIfolder. > > > > > > > > |
|
|
|
#9 |
|
Guest
Posts: n/a
|
thanks.
"Henry Gusakovsky" <h.ghusakovsky@gmail.com> wrote in message news:d28dmi$2q84@zubr.belcaf.minsk.by... > See some snipped > that is for Application pointer. ALL OOM pointers should be marshalled > like > this. > > MAPIFolder is thread safe so it can be easily passed between threads. > > > That peace of code from D.Box's book "Essential COM". > I've modified it a bit. > > HRESULT WritePtr(Outlook::_Application *pApplication, HGLOBAL& rhglobal) > { > IStream *pStm = 0; > ?hglobal = 0; > // alloc and wrap block of memory > HRESULT hr = CreateStreamOnHGlobal(0, FALSE, &pStm); > if (SUCCEEDED(hr)) { > // write marshaled object reference to memory > hr = CoMarshalInterface(pStm, __uuidof(Outlook::_Application), > pApplication, > MSHCTX_INPROC, 0, > MSHLFLAGS_NORMAL); > // extract handle to underlying memory > if (SUCCEEDED(hr)) > hr = GetHGlobalFromStream(pStm, &rhglobal); > pStm->Release(); > } > return hr; > } > > HRESULT ReadPtr(HGLOBAL hglobal, Outlook::_Application* &pApplication) > { > IStream *pStm = NULL; pApplication = NULL; > // wrap block of existing memory passed on input > HRESULT hr = CreateStreamOnHGlobal(hglobal, FALSE, &pStm); > if (SUCCEEDED(hr)) { > // get a pointer to the object that is legal in this apt. > hr = CoUnmarshalInterface(pStm, __uuidof(Outlook::_Application), > (void**)&pApplication); > pStm->Release(); > } > return hr; > } > > So you write pointer in the main thread and obtain HGLOBAL handle > pass that handle to the worker thread. In the thread call ReadPtr and > obtain > marshalled pointer. > use GlobalFree to free HGLOBAL handle. > > > > WBR > Henry > > "Semut" <ant_yio@hotmail.com> wrote in message > news:OXQXxq0MFHA.2736@TK2MSFTNGP09.phx.gbl... >> I will be utilizing the global variable of Outlook::_Application in my >> worker thread. >> >> Then, through the Application object, I obtain the Outlook::_Namespace >> variable and then the MAPIFolder. >> >> This is to avoid the security alert by Outlook. >> >> Will it be fine that way? >> >> Also, I will be passing a MAPIFolder to my worker thread function by >> >> myCall( spMAPIFolder.Detach()); >> >> so that my worker thread will release the ref count it self. It this ok? >> >> >> Ok, my worker thread function do call. >> >> ::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); >> >> ... >> >> ::CoUninitialize(); >> >> Previously, without calling these, the functions in the thread, >> especially >> those CoCreateInstance will fail. >> >> >> > The only you need is to obtain pointers to the OOM objects in the >> > proper >> > way. >> > >> > CoCreateInstance will do. >> > If it is existing object you shoud marshal it manualy between main > thread >> > an >> > the worker thread. >> >> Can you show a code snippet for that? >> Supposingly, I need to pass a MAPIFolder to my worker thread. How do I >> marshal or use the CoCreateInstance. (I am using Redemption and Extendded >> MAPI also, so you can show in Redemption also no problem, not bound to be >> OOM only. ) >> >> At the moment, the MAPIFolder smart pointer (CComPtr < Outlook :: > MAPIFolder >> > ) give me problem when it try to Release the ref count when it goes > out >> of the scope. In a non multi-threaded environment, this call was fine >> but >> when I switch to MT. The program will complain for error about the >> MAPIfolder. >> >> >> >> >> >> >> >> > > |
|
|
|
#10 |
|
Guest
Posts: n/a
|
thanks.
"Dmitry Streblechenko" <dmitry@dimastr.com> wrote in message news:ur7mvsVMFHA.384@TK2MSFTNGP10.phx.gbl... > You must call CoInitializeEx (or CoInitialize) in your secondary threads > if you are using COM on that thread. > > Dmitry Streblechenko (MVP) > http://www.dimastr.com/ > OutlookSpy - Outlook, CDO > and MAPI Developer Tool > > "Semut" <ant_yio@hotmail.com> wrote in message > news:eB54cqRMFHA.1948@TK2MSFTNGP14.phx.gbl... >> Ok, supposing I spawn my secondary thread and it will connect to network >> and update the MAPIFolder of the Outlook using OOM. In my main thread, >> the Outlook itself, I will probably do some work like adding items to the >> MAPIfolder manually. (probably the same MAPIFolder points to as the >> MAPIFolder spawned in the thread.) >> >> Do I need to call >> >> ::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);and >> ::CoUninitialize();in my secondary thread so that it will create two >> standard single threaded apartments?(or it is not necessary?)How to do >> about?thanks >> >> "Dmitry Streblechenko" <dmitry@dimastr.com> wrote in message >> news:O%237ZVKQMFHA.3420@tk2msftngp13.phx.gbl... >>> All Outlook objects are apartment threaded, so all the calls to the OOM >>> objects from a secondary thread will be marshlled to the main Outlook >>> thread. >>> You can of course do non-OOM processing on the secondary thread. >>> Extended MAPI and Redemption are thread-safe, but your mileage may vary >>> of course. >>> >>> Dmitry Streblechenko (MVP) >>> http://www.dimastr.com/ >>> OutlookSpy - Outlook, CDO >>> and MAPI Developer Tool >>> >>> "Semut" <ant_yio@hotmail.com> wrote in message >>> news:OPRGVlOMFHA.2704@TK2MSFTNGP15.phx.gbl... >>>> Hello, >>>> >>>> I am thinking of spawning a thread of processing the MAPIFolder >>>> selected everytime when the BeforeFolderSwitch was trigger. I overheard >>>> that Outlook VBA/OOM is a single threaded, is it true? And even if it >>>> is single threaded, can I do a multhreading programming? Any >>>> precautions that I need to look into or anyone has done it in the past. >>>> Reason I want to do this is my addin need to response to the network, >>>> sometimes there are some lagging occur in the network. >>>> >>>> By the way, I am using Redemption and extended MAPI too. Do these have >>>> issue on the multi-threading? >>>> >>>> thanks. >>>> >>>> >>>> >>> >>> >> >> > > |
|
![]() |
|
| Thread Tools | |
| Rate This Thread | |
|
|

Main Page 

