Multiple Threads and MAPI Sessions

If your voice mail server is connected to a number of phone lines, you may want to use multiple processing threads to service incoming calls. Once you have created a MAPI session, this session can be connected to only one mailbox at a time. If the voice mail server must handle twenty incoming calls at the same time, twenty MAPI sessions must be created.

Multiple MAPI sessions are able to access multiple mailboxes simultaneously by using a thread for each interaction. When the number of threads exceeds a certain limit (perhaps fifteen to twenty threads), context switching between threads begins to lower performance. The solution is to separate the user’s perception from the software that is actually executing. When a user asks to hear a message, instead of allocating a dedicated mailbox thread to that request, the request is queued for processing by one of a smaller number of mailbox access threads.

When the mailbox access thread is free, it opens the mailbox associated with the message, locates the message, and passes the message to a message reader thread that reads the message over the telephone to the user. This implementation gives good performance. Users tend to pause a long time between mailbox accesses while listening to messages and instructions, so a single mailbox access thread or message reader thread can easily handle mailbox access for many users.

Add well-designed caching, such as saving the contents tables for all the users currently online, and the application becomes even more efficient.

The MBLSAMPL sample application demonstrates privileged access by opening an information store and logging on to multiple mailboxes. Its sample code shows you how to specify the recipient’s name whose mailbox you want to access, and if successful, how to determine the number of new messages.

Special handling of messages is necessary in a multithreaded environment to avoid long-term blocking. A console application or a Windows NT service that is a MAPI client may need to handle messages in an initialization thread. To do this, the application must perform the following tasks:

  1. Call MsgWaitForMultipleObjects when the main thread blocks.
  2. Call the GetMessage, TranslateMessage, and DispatchMessage sequence of Win32 functions to handle the message when MsgWaitForMultipleObjects returns the sum of the value of the nCount parameter and the value of WAIT_OBJECT_0, indicating that a message is in the queue.

For more information about creating multithreaded applications, see Using MAPI in Multithreaded Applications.