System.Runtime.InteropServices.COMException(0x80030020):操作失败

时间:2017-12-08 08:35:20

标签: c# office-interop

我尝试使用以下方法将Outlook.MailItem保存到文件夹中

MailItem.SaveAs(path, Outlook.OlSaveAsType.olMSG)

大部分时间都可以正常使用。但是,当有大约20封电子邮件同时点击Outlook时,对于其中的一部分,我会遇到以下异常:

System.Runtime.InteropServices.COMException (0x80030020): The operation failed.
   at Microsoft.Office.Interop.Outlook._MailItem.SaveAs(String Path, Object Type)

我检查了代码0x80030020,这似乎意味着"发生了共享违规行为。"但是,我不确定这意味着什么。在我的应用程序中,我有以下两行,第一行将电子邮件保存到文件夹,第二种方法尝试将该文件发送到API:

file = MailItemHelper.SaveMailItemToOFEFolder(mailItem);
bool isEmailSentByHttp = MailItemHelper.SendMailItemToOFEApi(_userid, file)

路径包含电子邮件的主题,通过执行以下操作清除非字母数字字符:

Regex nonAlphaNumericRgx = new Regex(@"\W|_");
subject = nonAlphaNumericRgx.Replace(mail.Subject, "_");

1 个答案:

答案 0 :(得分:1)

我想我无法直接告诉问题是什么,但我可以尝试给你一些提示。

根据MS documentation,Outlook似乎正在使用StgOpenStorage函数,抛出STG_E_SHAREVIOLATION错误:

  

访问被拒绝,因为另一个来电者打开并锁定了该文件。

这意味着Outlook正在搞乱(用户点击"消息"并且outlooks锁定文件或其他内容)或者在使用正则表达式更改文件名后,您的字符串最终会变为与另一个文件相同,而它正在编写另一个文件。

你是如何与前景挂钩的?您的应用是否使用每封邮件的新主题?您可以添加log4net并在代码中记录所有操作,例如:

// receive and email and store subject name on var subject
log.Info($"E mail with subject '{subject}' arrived.");
// convert name and save on var newSubject
log.Info($"Mail will be saved as '{newSubject}'.");
// notify the beginning of the operation
log.Info("Calling MailItemHelper.SaveMailItemToOFEFolder.");
// notify the end of the operation
log.Info("Mail saved successfully.");
// notify Post in REST API
log.Info("Sending in MailItemHelper.SendMailItemToOFEApi");
// notify end of Post in REST API
log.Info("MailItemHelper.SendMailItemToOFEApi sent");

这将清楚地说明如何检索所有邮件,如果存在一些线程问题,您可以检查哪些邮件正在完成/首先启动。