How to read from exchange server asynchronously using IMoniker and IStream Interface

206 views Asked by At

Currently the MFCMAPI uses a single thread to serialize all of the MAPI calls. Mapi provider initializes and stores the folder name, etc as a member variable and then read the mailboxs.

This may result in the slow processing of the exchange messages and attachments. For example, it costly when query for attachment files and wait for it to return. So it would be better if can send a request to read the messages and at same time can do another process (initialize another message).

So, is it possible to query and read messages while initialize for the next next message by IMonikers and IBindStatusCallback::OnDataAvailable.

Or is there any other way to do that?

I have tried to use IMoniker and IStream to read data from exchange server asynchronously, I am trying to use BindToStorage to make an asynchronous bind and read date from OnDataAvailable. The binding code is shown as below.

hRes = CoInitialize(NULL);
CComPtr<IBindCtx> pbc;
CComPtr<IMoniker> pmk;
CComPtr <IStream> lpStream1;
ULONG chEaten = 0;

hRes = CreateBindCtx(0, &pbc);
OLECHAR string[] =
    L"Session:3!clsid:10000013-0000-0000-0000-000000000001";
if (FAILED(hRes = MkParseDisplayName(pbc, string, &chEaten, &pmk)))
{
    return 0;
}
hRes = pmk->BindToStorage(pbc, NULL, IID_IStream,reinterpret_cast<void **>(&lpStream1));

However when call BindToStorage, it returns Class not Registered. Does anyone know which part is wrong?

And Is that possible to read data from exchange server asynchronously by this method?

Thanks

2

There are 2 answers

2
Dmitry Streblechenko On

Admittedly it's been a while since I closely looked at the MFCMAPI source code, but I don't think it does anything like this.

If you want to retrieve the data asynchronously, you need to start a new thread, initialize MAPI, and do whatever lengthy operation you need to do on that thread.

What kind of data are you trying to read?

0
sgriffin On

MFCMAPI already uses a worker thread to handle QueryRows calls while loading a folder. Beyond that, I wasn't really targeting speed over code clarity/simplicity so I didn't bother with threading.

I'm ignoring your questions about IMoniker and BindToStorage because, for the most part, MAPI is not COM, so I don't see what they have to do with spinning up threads to run MAPI code. If you want to read a stream from a worker thread, just make sure you initialize MAPI on that thread.

Are you trying to redo part of MFCMAPI itself or are you writing code for your own application, using MFCMAPI as a model? If within MFCMAPI, what specific scenario are you targeting?