Home How to release Outlook MailItem correct?
Reply: 4

How to release Outlook MailItem correct?

Wowa
1#
Wowa Published in 2010-12-14 09:03:45Z

I just can't release my Outlook MailItems. After opening 200 Mails the Exchange Sever returns the maximum open Emails is reached.

I'm remove my UserProperty from all selected Mail.

My Code:


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();
  //----------------------------------
 }
}

Any idea what's wrong?

Bolu
2#
Bolu Reply to 2010-12-14 12:34:59Z

You can try this: Instead of defining a new MailItem everytime within the For loop, can you define mi outside the For loop or even in your class level, and reuse it for each mailitems? e.g:

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();

EDIT:

Try to create local variable for each references e.g:

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

EDIT-2:

IF you are using Outlook 2010 check this: Outlook 2010 addin selection not clearing

Sandeep Singh Rawat
3#
Sandeep Singh Rawat Reply to 2010-12-14 10:48:29Z

Try to replace foreach with a for loop and do the following

GC.Collect();
GC.WaitForPendingFinalizer()
GC.Collect();

Also remove all the reference to any outlook COM object that you might be using.

Wowa
4#
Wowa Reply to 2010-12-14 13:38:56Z

I believe its any kind of bug like Bolu said. Again much thanks for your help Bolu.

I'm now using following workaround:

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;
}
Val Cool
5#
Val Cool Reply to 2012-02-10 14:40:46Z

Just put the releasing method outside the main if condition. Items get referenced even when you just loop through them with the foreach loop. Write

Marshal.ReleaseComObject(mi)

right before the last "}". This works for me. I read that generally you have to release every COM object explicitly.

You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.335114 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO