C# Outlook 2010 VSTO加载项:用户界面在向PST异步添加文件夹时随机冻结

C# Outlook 2010 VSTO加载项:用户界面在向PST异步添加文件夹时随机冻结,c#,.net,outlook,vsto,outlook-addin,C#,.net,Outlook,Vsto,Outlook Addin,My C#VSTO Outlook 2010加载项将数百个MAPI文件夹异步添加到导入的pst文件中。(pst存在于Outlook foldertree中) 以下是一个例子: Task.Factory.StartNew(() => { ... //get pstStore var rootFolder = pstStore.GetRootFolder(); for (int i = 0; i < 500; i++) { var folder

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

以下是一个例子:

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);
});
Task.Factory.StartNew(()=>{
…//获取PST存储
var rootFolder=pstStore.GetRootFolder();
对于(int i=0;i<500;i++)
{
var folder=rootFolder.Folders.Add(“Test”+DateTime.Now.Ticks);
Thread.SpinWait(1000);//模拟工作
Marshal.ReleaseComObject(文件夹);
}
Marshal.ReleaseComObject(根文件夹);
});
Outlook UI在
rootFolder.Folders.Add(…)
处随机冻结2-3秒。有时20后,有时50后添加文件夹


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

希望您的加载项在Outlook 2013或更新版本中完全停止工作:OOM检测到正在从Outlook主线程以外的线程调用它时,会立即引发错误。请注意,这仅适用于在outlook.exe地址空间内运行的COM加载项。进程外访问总是由COM系统封送到Outlook主线程(但这违背了从单独线程使用OOM的全部目的)

辅助线程上只能使用扩展MAPI(C++或Delphi)。如果using是一个选项(可以从包括C#在内的任何语言使用),则它可以在次线程上使用:在主线程(它是IMAPISession MAPI接口)上存储Namespace.MAPIOBJECT属性的值,然后在次线程上创建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);
}
对象映射对象//在班级/全球层面
..
mapiObject=Application.Session.mapiObject;
...
Task.Factory.StartNew(()=>{
Redemption.RDOSession会话=新建Redemption.RDOSession();
session.MAPIOBJECT=MAPIOBJECT;
Redemption.RDOStore pstStore=session.Stores[“YourStoreName”];
Redemption.RDOFolder rootFolder=pstStore.IPMRootFolder;
Redemption.RDOFolders folders=rootFolder.folders;
对于(int i=0;i<500;i++)
{
var folder=folders.Add(“Test”+DateTime.Now.Ticks);
Marshal.ReleaseComObject(文件夹);
}
封送.释放对象(文件夹);
Marshal.ReleaseComObject(根文件夹);
发布对象元帅(会议);
}

+1编写此详细提示。我正在考虑使用c++/cli和IMAPIFolder::CreateFolder(…)如果失败了,你的答案会被接受,我会买你的救赎库。我设法让它用C++ + CLI和扩展的MAPI工作。速度的差别是惊人的。对于不熟悉管理C++的人,我建议赎回!接受答案。