Outlook Addin:使用线程

时间:2013-05-12 08:25:59

标签: outlook vsto outlook-addin outlook-redemption

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

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

  • 我尝试从我的主线程和我的工作线程初始化我的RDOSession。
  • 我尝试在主线程上获取MAPIFolders,并且只使用工作线程上的MAPITable

目前,唯一对我有用的是在主线程上运行我的所有逻辑(在按钮点击事件中),然而这会长时间锁定Outlook的用户界面,这是用户的观点所不能接受的。图。

是否有人指出如何使用Outlook Addin中的后台线程?

2 个答案:

答案 0 :(得分:3)

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

  1. 使用Thread类创建新线程,并将其设置为STA。

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

  3. 完成后,在您使用的每个COM对象上使用“Marshal.ReleaseComObject”。这可能是导致不稳定的原因,因为当它的对象太长时,Outlook真的不喜欢。例如,这行代码“var table = rdoFolder.Items.MAPITable;”创建两个COM对象:RDOItems和MAPITable,必须释放它们,因此您需要拆分此行以保存对RDOItems对象的引用。

  4. 调用GC.CollectApplication.DoEvents因为如果你没有在所有COM对象上调用Marshal.ReleaseComObject,终结器将尝试释放它们并将挂起,因为COM对象是在线程上创建的不抽取消息循环,它的终结器方法必须在创建它们的线程上运行。

  5. 如果可以,请启动辅助进程并在单独的进程中执行此循环。这将使用户界面和后台工作之间达到最大程度的分离。

答案 1 :(得分:1)

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

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