该进程无法访问该文件,因为它正由另一个进程使用

时间:2012-10-04 07:36:58

标签: c# asp.net

我正在使用以下代码在本地驱动器中创建包含内容的文件。

File.WriteAllLines(path, contents);

我将此文件附加到邮件中并发送给团队。一旦发送邮件我需要删除该文件,删除我在代码下面使用的文件,但我收到运行时错误

File.Delete(path);

错误消息:进程无法访问该文件,因为它正由另一个进程使用

默认情况下,WriteAllLines()方法关闭文件,但仍由另一个进程打开。我只能在一段时间后通过执行代码来删除文件,但这不是场景。邮件发送后我需要删除它。

更新

System.Net.Mail.MailMessage mailMessage = new System.Net.Mail.MailMessage();

       mailMessage.To.Add(new System.Net.Mail.MailAddress(recipient, ToName));

       mailMessage.From = new System.Net.Mail.MailAddress(From, FromName);
       mailMessage.Subject = Subject; // "Outlook calendar as attachment";  // modified by Srikanth J on 28/06/2012
       mailMessage.Body = "This is a test message";

       System.Net.WebClient webclient = new System.Net.WebClient();

       webclient.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;

       for (int i = 0; i < item.Attachments.Count; i++)
       {
           string url = item.Attachments.UrlPrefix + item.Attachments[i];
           SPFile file = item.ParentList.ParentWeb.GetFile(url);
           mailMessage.Attachments.Add(new System.Net.Mail.Attachment(file.OpenBinaryStream(), file.Name));

       }

       System.Net.Mail.Attachment mailAttachment = new System.Net.Mail.Attachment(path);

       mailMessage.Attachments.Add(mailAttachment);
       smtp.Send(mailMessage);

任何帮助都是适当的,谢谢。

5 个答案:

答案 0 :(得分:15)

MailMessage实现IDisposable,因此您应该使用using关键字在完成任务后释放任何资源。如果你不这样做,是的,文件仍然可以使用,直到垃圾收集器发现你不再使用该消息为止。

using (var mailMessage = new MailMessage())
{
   // set mailMessage properties
   // ...
   smtp.Send(mailMessage);
}

您也可以直接致电Dispose获取附件,但处理消息已经确保所有子对象(包括附件)都能正确处理。

答案 1 :(得分:2)

只需在

中添加一个简单的Using语句即可
  System.Net.Mail.MailMessage mailMessage = new System.Net.Mail.MailMessage(); 

以这种方式改变

 using(System.Net.Mail.MailMessage mailMessage = new System.Net.Mail.MailMessage())
 {
       .......
        smtp.Send(mailMessage); 
 }

当你的代码退出using语句时,mailMessage对象也将被处理掉每个实现IDisposable接口的对象。这意味着,附件集合中的每个附件都将被处置,您的文件不再被锁定。

答案 2 :(得分:1)

如果你想这样做,我建议把你的文件写入Stream而不是文件。

这样,您可以完全避免文件锁定问题。

以下是一个示例,说明如何基于流设置附件(此处未显示编写流本身的代码)。

private static void SendReport(Report report)
{
    MailMessage msg = new MailMessage
    {
        From = new MailAddress(Configuration.EmailFrom),
        Subject = Configuration.EmailSubject,
        Body = Configuration.EmailBody
    };

    msg.To.Add(Configuration.EmailTo);

    if (!string.IsNullOrWhiteSpace(Configuration.EmailCC))
        msg.CC.Add(Configuration.EmailCC);

    if (!string.IsNullOrWhiteSpace(Configuration.EmailBcc))
        msg.Bcc.Add(Configuration.EmailBcc);

    Program.AttachReport(report, msg);

    SmtpClient smtp = new SmtpClient();
    smtp.Send(msg);
}

private static void AttachReport(Report report, MailMessage message)
{
    Stream stream = new MemoryStream();
    report.Save(stream, Configuration.SurveyName);
    message.Attachments.Add(new Attachment(stream, Configuration.AttachmentName, Configuration.AttachmentMediaType));
}

答案 3 :(得分:1)

试试这个

File.WriteAllLines(path, contents);
using(System.Net.Mail.MailMessage mailMessage 
                                = new System.Net.Mail.MailMessage())
{
// send mail containing the file here
}
File.Delete(path);

希望这有助于你。

答案 4 :(得分:0)

修改

try
{
  //send mail code
}
finally
{
  mailAttachment=null;
  mailMessage=null;
}
//delete file code 

我建议在发送邮件后最后释放文件句柄或关闭文件

try
{
  //attach file 
  //send mail
}
finally
{
  //set finally handle to null 
  // or close the file
}

//after this delete the file