8

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

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

任何帮助都是appriciated,谢谢。

4

5 回答 5

17

MailMessageimplements IDisposable,所以你应该在using完成后使用关键字来释放任何资源。如果你不这样做,是的,文件很有可能一直在使用,直到垃圾收集器碰巧注意到你不再使用该消息。

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

您也可以Dispose直接调用附件,但处理消息将确保所有子对象(包括附件)都得到正确处理。

于 2012-10-04T08:12:47.760 回答
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 接口的每个对象都将被释放。这意味着,附件集合中的每个附件都将被释放,您的文件不再被锁定。

于 2012-10-04T08:13:27.570 回答
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));
}
于 2012-10-04T07:59:00.430 回答
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);

希望这对你有帮助。

于 2012-10-04T08:16:57.907 回答
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 
于 2012-10-04T07:44:11.990 回答