Outlook加载项:使用线程

Outlook加载项:使用线程,outlook,vsto,outlook-addin,outlook-redemption,Outlook,Vsto,Outlook Addin,Outlook Redemption,我正在处理Outlook Addin,我必须处理大量项目。这需要相当多的时间,因此我尝试在不同的线程中运行处理(使用Task.Factory.StartNew)。然而,这会导致Outlook随机崩溃 我正在使用Redemption处理MAPITable,以减少工作量并仅加载相关数据 我已尝试从主线程和工作线程初始化RDOSession 我已尝试在主线程上获取MAPIFolders,并仅在工作线程上使用MAPITable 目前,对我来说唯一有效的方法是在主线程上运行我的所有逻辑(在按钮单击事件

我正在处理Outlook Addin,我必须处理大量项目。这需要相当多的时间,因此我尝试在不同的线程中运行处理(使用Task.Factory.StartNew)。然而,这会导致Outlook随机崩溃

我正在使用Redemption处理MAPITable,以减少工作量并仅加载相关数据

  • 我已尝试从主线程和工作线程初始化RDOSession
  • 我已尝试在主线程上获取MAPIFolders,并仅在工作线程上使用MAPITable
目前,对我来说唯一有效的方法是在主线程上运行我的所有逻辑(在按钮单击事件中),但是这会长时间锁定Outlook的用户界面,从用户的角度来看,这是不可接受的


是否有人对如何在Outlook插件中使用后台线程有一些指导意见?

在辅助线程中使用RDO对象有什么问题?只要在辅助线程上创建了RDOSession,MAPI就应该正确初始化


另外,TaskFactory使用线程池,您最好使用显式线程类,o至少确保不同线程之间不共享RDOSession-每个线程上都必须初始化MAPI。

在我的项目中有类似的代码,我建议如下:

  • 使用thread类创建新线程,并将其设置为STA

  • 使用“session.Logon(“profileName”,NoMail:true,NewSession:false);”登录会话,而不使用MAPIOBJECT。我发现它比使用MAPIOBJECT有更好的性能,我猜它仍然会将一些调用封送回主线程,因为MAPIOBJECT是在主线程上创建的

  • 在使用完每个COM对象后,立即对其使用“Marshal.ReleaseComObject”。这可能是导致不稳定的原因,因为Outlook确实不喜欢将其对象保留太长时间。例如,这行代码“var table=rdoFolder.Items.MAPITable;”创建两个COM对象:RDOItems和MAPITable,这两个对象都必须释放,所以您需要拆分此行以保留对RDOItems对象的引用

  • 调用,因为如果不在所有COM对象上调用Marshal.ReleaseComObject,终结器将尝试释放它们并将挂起,因为COM对象是在不泵送消息循环的线程上创建的,并且它的终结器方法必须在创建它们的线程上运行

  • 如果可以,启动一个辅助进程,并在单独的进程中执行此循环。这将最大限度地分离UI和后台工作


  • 下面是一个示例非工作代码,它会导致Outlook崩溃:尝试使用{}定义RDOSession变量的作用域并调用GC.Collect();在所有RDO对象都超出范围之后。