5

我只是无法释放我的 Outlook MailItems。打开 200 封邮件后,Exchange 服务器返回已达到的最大打开邮件数。

我要从所有选定的邮件中删除我的 UserProperty。

我的代码:


foreach (var selection in Globals.ThisAddIn.Application.ActiveExplorer().Selection)
{
 if (selection is MailItem)
 {
  MailItem mi = (MailItem)selection;
  UserProperty up = mi.UserProperties.Find("MyProp");
  if (up != null)
  {
   up.Delete();
   //##################################
   // I also tried :
   //----------------------------------
   //    Marshal.ReleaseComObject(up);
   //    up = null;
   //----------------------------------
  }

  mi.Save();

  //##################################
  // I also tried :
  //----------------------------------
  //     mi.Close(OlInspectorClose.olDiscard);
  //----------------------------------


  // I don't know if this loop is necessary, but I have found it somewhere on the web
  while (Marshal.ReleaseComObject(mi) > 0);
  mi = null;

  //##################################
  // I also tried :
  //----------------------------------
  //    GC.Collect();
  //    GC.WaitForPendingFinalizers();
  //----------------------------------
 }
}

知道有什么问题吗?

4

5 回答 5

3

我相信它像博卢所说的任何一种错误。再次非常感谢您的帮助博卢。

我现在正在使用以下解决方法:

List entryids = new List();

foreach (var selection in Globals.ThisAddIn.Application.ActiveExplorer().Selection)
{
    MailItem mi = selection as MailItem;
    if (mi != null)
    {
        // For any reason it's not possible to change the mail here

        entryids.Add(mi.EntryID);

        Marshal.ReleaseComObject(mi);
        mi = null;

    }
}

foreach (string id in entryids)
{
    MailItem mi = Globals.ThisAddIn.Application.ActiveExplorer().Session.GetItemFromID(id);

    // My changes on the mail

    mi.Save();
    Marshal.ReleaseComObject(mi);
    mi = null;
}
于 2010-12-14T13:38:56.617 回答
3

你可以试试这个:你可以在循环之外甚至在你的类级别定义一个新的,而不是在循环中MailItem每次都定义一个新的,并为每个邮件项重用它?例如:FormiFor

MailItem mi;
foreach (var selection in Globals.ThisAddIn.Application.ActiveExplorer().Selection)
{
 if (selection is MailItem)
 {   
   mi= (MailItem)selection;
   // your other code...
 }
 }
mi=null;
GC.Collect();
GC.WaitForPendingFinalizers();

编辑:

尝试为每个引用创建局部变量,例如:

Outlook.Explorer myExplorer=Application.ActiveExplorer(); 
Outlook.Selection mySelection=myexplorer.Selection; 
foreach (var selection in mySelection)
{
}
myExplorer=null;
mySelection=null;
//....

编辑-2:

如果您使用的是 Outlook 2010,请检查: Outlook 2010 addin selection not clearing

于 2010-12-14T10:28:03.873 回答
2

尝试用 for 循环替换 foreach 并执行以下操作

GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();

还要删除对您可能正在使用的任何 Outlook COM 对象的所有引用。

于 2010-12-14T10:48:29.797 回答
1

只需将释放方法放在主要if条件之外。即使您只是使用 foreach 循环遍历它们,也会引用项目。写

Marshal.ReleaseComObject(mi)

就在最后一个“ }”之前。这对我有用。我读到通常您必须明确释放每个 COM 对象。

于 2012-01-29T12:41:59.237 回答
1

您正在使用多点表示法 ( mi.UserProperties.Find),这意味着编译器会创建一个隐式变量来保存mi.UserProperties调用的结果;您不能显式释放该变量。该对象持有对其父MailItem对象的引用。

将其存储在显式变量中并使用Marshal.ReleaseComObject. UserProperty up变量同上。

此外,不要foreach与 Outlook 集合一起使用 - 该循环包含对所有项目的引用,直到循环退出。使用for循环并在完成该项目后立即在循环的每个步骤上显式释放项目

  Selection selectedItems = Globals.ThisAddIn.Application.ActiveExplorer().Selection; 
  for (int i = 1; i <= selectedItems .Count; i++)
  {
    object selection= selectedItems[i];
    MailItem mi = selection as MailItem;
    if (mi != null) //can have items other than MailItem
    {
      UserProperties props = mi.UserProperties;
      UserProperty up = props .Find("MyProp");
      if (up != null)
      {
        ...
        Marshal.ReleaseComObject(up);
      };
      Marshal.ReleaseComObject(props);
      Marshal.ReleaseComObject(mi);
    }; //if   
    Marshal.ReleaseComObject(selection);
  }; //for  
于 2018-12-01T18:43:03.980 回答