Outlook Addin:使用线程

Sag*_*tay 6 outlook vsto outlook-addin outlook-redemption

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

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

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

目前,唯一对我有用的是在主线程上运行我的所有逻辑(在按钮单击事件中),但是这会长时间锁定Outlook的用户界面,从用户的角度来看这是不可接受的.

有没有人有一些关于如何使用Outlook Addin中的后台线程的指针?

Art*_*hur 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. 如果可以,请启动辅助进程并在单独的进程中执行此循环。这将使用户界面和后台工作之间实现最大程度的分离。