连续两次保存同一邮件时出错

时间:2018-01-31 11:41:17

标签: c# vsto outlook-addin mapi outlook-2013

尝试在Outlook中使用UserProperties的{​​{1}}添加一些自定义信息时,我发现邮件无法连续两次保存而不会引发异常

  

由于消息已经执行,因此无法执行操作   改变。

我一直在研究它,有些人建议它可能与不正确释放COM对象有关,因此我将代码移动到新的AddIn,在那里测试它确保所有对象都被正确释放并且例外还在那里。这让我认为问题与IMAP同步有关,因为我使用gmail帐户来测试AddIn。但如果是这种情况,我该怎么做才能避免出现这种异常?这是我的代码:

  

注意:每次用户单击选中邮件的按钮时,都会执行该代码。第一次   MailItem设置为UserProperty,第二次设置为foo,因为它是相同的   mail并且它具有名为custom property的属性,它将值更改为   bar。   第二次对同一邮件执行mail.Save()时会引发异常。

    Explorer explorer = null;
    Selection selection = null;
    MailItem mail = null;
    UserProperties props = null;
    UserProperty prop = null;

    try
    {
        app = Globals.ThisAddIn.Application;
        explorer = app.ActiveExplorer();
        selection = explorer.Selection;            
        mail = selection[1] as MailItem;

        string customProperty = "Custom property";
        props = mail.UserProperties;
        prop = props.Find(customProperty);
        if (prop == null)
        {
           prop = props.Add(customProperty, OlUserPropertyType.olText);
           prop.Value = "foo";
           Debug.WriteLine("added property: foo");
        }
        else
        {
           prop.Value = "bar";                            
           Debug.WriteLine("change property: bar");
        }

        mail.Save();

    }
    catch (System.Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
    finally
    {
        if (prop != null && Marshal.IsComObject(prop))
            Marshal.ReleaseComObject(prop);

        if (props != null && Marshal.IsComObject(props))
            Marshal.ReleaseComObject(props);

        if (mail != null && Marshal.IsComObject(mail))
            Marshal.ReleaseComObject(mail);

        if (selection != null && Marshal.IsComObject(selection))
            Marshal.ReleaseComObject(selection);

        if (explorer != null && Marshal.IsComObject(explorer))
            Marshal.ReleaseComObject(explorer);       
    }

我已经尝试过等一段时间再次保存邮件,但时间似乎并不重要。有什么建议吗?

  

注意2:当邮件放入邮件时,代码可以正常运行   本地文件夹。

     

注意3:禁用Outlook reading pane,允许我保存   邮件再一次,第三次引发异常,但保存它   如果我第四次尝试,请正确

1 个答案:

答案 0 :(得分:0)

您是否仅在主线程上运行代码?你运行辅助线程吗?

在代码中,您可以检查属性值及其值。如果该值等于您需要设置的值,则无需分配相同的值。在这种情况下,您可以设置一个标记,表示该项目未进行任何更改,并取消Save电话。

    bool skipSave = false;
    if (prop == null)
    {
       prop = props.Add(customProperty, OlUserPropertyType.olText);
       prop.Value = "foo";
       Debug.WriteLine("added property: foo");
    }
    else
    {
       if(prop.Value != "bar")
       {
          prop.Value = "bar";
          Debug.WriteLine("change property: bar");
       }
       else
          skipSave = true;                        
    }

    if(!skipSave)
       mail.Save();