场景:我编写了一个应用程序来打开 .msg 文件列表(已转储到文件系统),从中获取一些信息(主题,抄送),然后移动它们。
问题:但是,当涉及到移动文件时,我收到以下错误:
该进程无法访问该文件,因为该文件正在被使用 另一个过程。
对文件运行句柄仅显示我编写的工具,没有其他句柄。
因此,我认为当我完成将文件用作 Redemption MessageItem 对象时,我没有正确释放这些文件。
但是我无法将它们包装在 using 语句中,因为它们没有实现 IDisposable。并且它们不会公开任何公共 Close 或 Dispose 或类似命名的方法。
总而言之,我想问的是:
a) 如何强制我的 C# 应用程序关闭给定的句柄,只知道文件句柄的路径?
或者
b) 有没有办法强制关闭 Redemption 对象?
var util = new MAPIUtilsClass();
MessageItem item = util.GetItemFromMsgFile(EmailPath, false);
item.Import(EmailPath, 3);
Subject = item.Subject;
From = (item.SenderName.Length < 96) ? item.SenderName : item.SenderName.Substring(0, 93) + "...";
To = (String.IsNullOrEmpty(item.To)) ? String.Empty : (item.To.Length < 96) ? item.To : item.To.Substring(0, 93) + "...";
CC = (String.IsNullOrEmpty(item.CC)) ? String.Empty : (item.CC.Length < 96) ? item.CC : item.CC.Substring(0, 93) + "...";
Sent = item.SentOn;
Received = item.ReceivedTime;
Log.Write("Redemption: Email data harvested" + EmailPath);
完成后尝试致电
util.CleanUp
。
请勿使用
MAPIUtils.GetItemFromMsgFile
- 它已被弃用。
使用 RDOSession.GetMessageFromMsgFile
(或 CreateMessageFromMsgFile
) - 它返回支持 IRDOMail
的 IDisposable
对象。
按照 Daniel 的建议使用 Util.CleanUp() 方法,但立即使用 GC.Collect() 来成功,并将其放在 try-catch 的 finally 语句中。
所以代码现在看起来像这样:
MAPIUtilsClass util = null;
try
{
util = new MAPIUtilsClass();
MessageItem item = util.GetItemFromMsgFile(EmailPath, false);
item.Import(EmailPath, 3);
Subject = item.Subject;
From = (item.SenderName.Length < 96) ? item.SenderName : item.SenderName.Substring(0, 93) + "...";
To = (String.IsNullOrEmpty(item.To)) ? String.Empty : (item.To.Length < 96) ? item.To : item.To.Substring(0, 93) + "...";
CC = (String.IsNullOrEmpty(item.CC)) ? String.Empty : (item.CC.Length < 96) ? item.CC : item.CC.Substring(0, 93) + "...";
Sent = item.SentOn;
Received = item.ReceivedTime;
util.Cleanup();
Log.Write("Redemption: Email data harvested: " + EmailPath);
}
catch (Exception exp)
{
Log.Write(String.Format("Error using Redemption API against: {0}\r\n{1}\r\n{2}",
this.EmailPath, exp.Message, exp.StackTrace));
}
finally
{
if (util != null)
util.Cleanup();
GC.Collect();
}