Outlook 2016 аварийно завершает работу mapi.MAPIUninitialize()

В моем многопоточном приложении, где несколько потоков инициализируются mapiinitialize с помощью

mapi.MAPIInitialize((0, mapi.MAPI_MULTITHREAD_NOTIFICATIONS))

mapi.MAPIUninitialize() crashes. I got the following call stack from windbg.

mso30win32client!Ordinal250+0x32423    
mso30win32client!Ordinal126+0x5b   
mso30win32client!Ordinal1337+0x39d   
mso30win32client!Ordinal1470+0x17e    
mso30win32client!Ordinal1470+0xe    
mso40uiwin32client!Ordinal2408+0x19    
olmapi32!LINKEDLIST_RemoveKey+0x4e6   
olmapi32!HrUninitMso+0x36    
olmapi32!MAPIUninitialize+0x9    
MSMAPI32!MAPIUninitialize+0x42   
MAPI32!MAPIUninitialize+0x5b    
mapi+0x11d9    

Каждый поток последовательно выполняет только следующие вызовы mapi(Outlook 2016):
1 MAPIInitialize
2 MAPIAdminProfiles
3 HrQueryAllRows
4 session=MAPILogonEx
5 session.logoff
6 MAPIUninitialize

Наблюдение:
Если есть два потока T1 и T2.
T1 входит в сеанс до T2, а T1 выполняет MAPIUninitialize после T2, это не приводит к сбою,
Но если T1 входит в сеанс до T2 и T1 выполняет MAPIUninitialize до T2, а затем вызов MAPIUninitialize приводит к сбою с указанным выше стеком.

Сбой в Outlook 2016 отлично работает только с Outlook 2013 и более ранними версиями.


person mitali c    schedule 01.12.2015    source источник
comment
У меня похожая ошибка, но с Access OLEDB Engine (часть Office Access 2016), - stackoverflow.com/questions/37432816/ Попробуйте обновить Office до последней версии.   -  person 23W    schedule 25.05.2016


Ответы (2)


Используется ли T1 в основном потоке, а T2 во вторичном?

Ознакомьтесь с правилами многопоточности MAPI страница, на которой указано следующее:

Если MAPI_MULTITHREAD_NOTIFICATIONS не используется, первый поток, вызвавший MAPIInitialize, должен жить дольше, чем все остальные потоки MAPI, и должен вызывать MAPIUninitialize последним.

Похоже, что упомянутый флаг сейчас не играет никакой роли, и вам следует сохранить последовательность вызовов, т.е. использовать LIFO (последний вошел, первый вышел).

person Eugene Astafiev    schedule 01.12.2015
comment
Здесь T1 и T2 - это потоки на уровне Sibling, созданные потоком, скажем, M. Thread M не выполняет никаких вызовов mapi. Следовательно, я не делаю mapi.MAPIInitialize и mapi.MAPIUninitialize для потока M. Может ли это быть проблемой? - person mitali c; 01.12.2015

Убедитесь, что вы вызываете MAPIInitialize в основном потоке до запуска T1 и T2 и вызываете MAPIUninitialize после завершения обоих потоков.

person Dmitry Streblechenko    schedule 01.12.2015
comment
Обязательно ли вызывать MAPIInitialize и MAPIUninitialize в основном потоке из Outlook 2016, поскольку он отлично работает для Outlook 2013 и более ранних версий. MAPIInitialize в основном потоке перед запуском T1 и T2 и MAPIUninitialize после завершения обоих потоков завершается ошибкой. Но если я вызову MAPIInitialize , MAPILogonEx в основном потоке до запуска T1 и T2, а выход из системы и MAPIUninitialize после выхода обоих потоков, все работает нормально. Есть ли какая-либо связь с основным потоком. - person mitali c; 01.12.2015
comment
Да. Первый поток, вызвавший MAPIInitialize, рассматривается системой MAPI как основной поток, в котором создаются элементы, имеющие сходство с потоком (дескрипторы окон и т. д.). Если то, что MAPI считает основным потоком, будет уничтожено, в то время как другой поток все еще использует MAPI, обязательно произойдут плохие вещи. Это не особенность 2016 года. Вам просто повезло раньше. - person Dmitry Streblechenko; 01.12.2015
comment
1. MAPIInitialize в основном потоке до запуска T1 и T2 и MAPIUninitialize для основного потока после завершения обоих потоков также приводят к сбою. Только если я вызываю MAPIInitialize , MAPILogonEx в основном потоке до запуска T1 и T2, а выход из системы и MAPIUninitialize после завершения обоих потоков работает нормально. система MAPI будет основным потоком? - person mitali c; 01.12.2015
comment
Необходимо обрабатывать запросы на несколько действий, создавая поток для каждого действия. Поскольку нет порядка, в котором каждый поток запускается и выходит, поэтому я делаю MAPIInitialize, MAPILogonEx и Logoff, MAPIUninitialize для каждого потока. Существует вероятность того, что только один поток запускается и выполняет MAPIInitialize, MAPILogonEx и выход из системы, MAPIUninitialize и завершает работу. Или несколько потоков начинают выполнять MAPIInitialize, MAPILogonEx и выход из системы, MAPIUninitialize параллельно, каждый в своем собственном контексте и завершается в произвольном порядке. - person mitali c; 02.12.2015
comment
IMAPISession может совместно использоваться несколькими потоками. Вызов MAPIInitialize/MAPILogonEx в основном потоке. Создайте вторичные потоки, в каждом потоке вызовите MAPIInitialize и используйте IMAPISession из основного потока. - person Dmitry Streblechenko; 02.12.2015
comment
Что может быть возможной причиной сбоя, когда несколько потоков создают несколько сеансов? - person mitali c; 02.12.2015
comment
Я не знаю. Но создание сеанса в основном потоке и совместное использование его с дополнительными потоками работает во всех версиях Outlook. - person Dmitry Streblechenko; 03.12.2015