【问题标题】:Outlook 2016 mapi.MAPIUninitialize() crashesOutlook 2016 mapi.MAPIUninitialize() 崩溃
【发布时间】:2015-12-01 05:46:36
【问题描述】:

在我的多线程应用程序中,多个线程通过映射初始化

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 MAPII初始化
2 MAPIAdminProfiles
3 HrQueryAllRows
4 会话=MAPILogonEx
5 会话.注销
6 MAPIUninitialize

观察:
如果有两个线程 T1 和 T2 .
T1 在 T2 之前登录到会话,并且 T1 在 T2 之后执行 MAPIUninitialize 它不会导致崩溃,
但是,如果 T1 在 T2 之前登录会话,并且 T1 在 T2 之前执行 MAPIUninitialize,则调用 MAPIUninitialize 会导致上述堆栈崩溃。

在 Outlook 2016 中出现崩溃,仅适用于 Outlook 2013 及更低版本。

【问题讨论】:

标签: multithreading ms-office office365connectors


【解决方案1】:

T1 用在主线程上,T2 用在辅助线程上吗?

查看MAPI Multithreading Rules 页面,该页面声明如下:

如果不使用 MAPI_MULTITHREAD_NOTIFICATIONS,第一个调用 MAPIInitialize 的线程应该比所有其他 MAPI 线程的寿命更长,并且应该是最后一个调用 MAPIUninitialize 的线程。

看起来提到的标志现在没有任何作用,您应该保留调用顺序,即使用 LIFO(后进先出)。

【讨论】:

  • 这里 T1 和 T2 是同级级别的线程,由一个线程说 M 创建。线程 M 不执行任何 mapi 调用因此我没有为线程 M 执行 mapi.MAPIInitialize 和 mapi.MAPIUninitialize。是这可能是问题吗?
【解决方案2】:

确保在 T1 和 T2 启动之前在主线程上调用 MAPIInitialize,并在两个线程退出后调用 MAPIUninitialize。

【讨论】:

  • 是否必须在 Outlook 2016 的主线程上调用 MAPIInitialize 和 MAPIUninitialize,因为它适用于 Outlook 2013 和更早版本。在 T1 和 T2 启动之前在主线程上进行 MAPIIinitialize 并在两个线程退出后进行 MAPIUninitialize 失败。但是,如果我在 T1 和 T2 启动之前在主线程上调用 MAPIInitialize , MAPILogonEx 并在两个线程退出后注销和 MAPIUninitialize 它工作正常是否与主线程有任何关系。
  • 是的。 MAPI 系统将调用 MAPIInitialize 的第一个线程视为创建具有线程关联性(窗口句柄等)的事物的主线程。如果 MAPI 认为的主线程被杀死,而另一个线程仍在使用 MAPI,那么肯定会发生不好的事情。这不是 2016 年特定的。你以前运气不错。
  • 1.T1 和T2 启动前主线程上的MAPIIinitialize 和两个线程退出后主线程上的MAPIUninitialize 也会导致崩溃。仅当我在 T1 和 T2 启动之前在主线程上调用 MAPIInitialize 时,MAPILogonEx 并且在两个线程退出后注销和 MAPIUninitialize 工作正常 2.即使 MAPI_MULTITHREAD_NOTIFICATIONS 标志为所有线程在 MAPIInitialize 中传递,第一个调用 MAPIInitialize 的线程被认为是MAPI 系统成为主线程?
  • 需要通过为每个活动生成线程来处理多个活动请求。由于没有每个线程启动和退出的顺序因此我正在为每个线程执行 MAPIIinitialize、MAPILogonEx 和 Logoff、MAPIUninitialize。有可能只有一个线程启动并执行 MAPIIinitialize 、MAPILogonEx 和 Logoff 、MAPIUninitialize 并退出 或者多个线程并行启动执行 MAPIIinitialize 、MAPILogonEx 和 Logoff 、MAPIUninitialize ,每个线程都在自己的上下文中并以某种随机顺序退出。
  • IMAPISession 可以在多个线程之间共享。在主线程上调用 MAPIInitialize / MAPILogonEx。生成辅助线程,在每个线程上调用 MAPIInitialize 并从主线程使用 IMAPISession。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-21
  • 2016-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多