Outlook 2010 VSTO 加载项:UI 随机冻结,同时将文件夹异步添加到 PST

Outlook 2010 VSTO AddIn: UI freezes randomly, while adding folders to PST asynchronously

我的 C# VSTO Outlook 2010 加载项将数百个 MAPI 文件夹异步添加到导入的 pst 文件。 (pst 存在于 Outlook 文件夹树中)

这是一个例子:

Task.Factory.StartNew(() => {
    ... //get pstStore
    var rootFolder = pstStore.GetRootFolder();
    for (int i = 0; i < 500; i++)
    {
      var folder = rootFolder.Folders.Add("Test" + DateTime.Now.Ticks);
      Thread.SpinWait(1000); //emulate work
      Marshal.ReleaseComObject(folder);
    }
    Marshal.ReleaseComObject(rootFolder);
});

Outlook UI 随机冻结在 rootFolder.Folders.Add(...) 2-3 秒。有时20后,有时50后添加文件夹。

任何帮助/提示将不胜感激。

希望您的插件在 Outlook 2013 或更新版本中完全停止工作:一旦 OOM 检测到它是从主 Outlook 线程以外的线程调用的,就会立即引发错误。请注意,这仅适用于 COM 插件,因为它们 运行 在 outlook.exe 地址 space 内。 Out-of-proc 访问总是由 COM 系统编组到主 Outlook 线程(但这违背了从单独线程使用 OOM 的全部目的)。

只能在辅助线程上使用扩展 MAPI(C++ 或 Delphi)。如果使用 Redemption is an option (it can be used from any language including C# - I am its author), its RDO family of objects 可以在辅助线程上使用:将 Namespace.MAPIOBJECT 属性 的值存储在主线程上(它是 IMAPISession MAPI 接口),然后在辅助线程上创建 RDOSession 对象的实例(将在该线程上初始化 MAPI)并将 RDOSession.MAPIOBJECT 属性 设置为存储在主线程上的值 - 这样两者将共享相同的值MAPI 会话。

超出我的想象:

object mapiObject; //on the class/global level
..
mapiObject = Application.Session.MAPIOBJECT;
...
Task.Factory.StartNew(() => {
  Redemption.RDOSession session = new Redemption.RDOSession();
  session.MAPIOBJECT = mapiObject;
  Redemption.RDOStore pstStore = session.Stores["YourStoreName"];
  Redemption.RDOFolder rootFolder = pstStore.IPMRootFolder;
  Redemption.RDOFolders folders = rootFolder.Folders;
  for (int i = 0; i < 500; i++)
  {
     var folder = folders.Add("Test" + DateTime.Now.Ticks);
     Marshal.ReleaseComObject(folder);
  }
  Marshal.ReleaseComObject(folders);
  Marshal.ReleaseComObject(rootFolder);
  Marshal.ReleaseComObject(session);
}