我收到了以下代码
protected override void Render(HtmlTextWriter writer)
{
// Write the HTML into this string builder
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
HtmlTextWriter hWriter = new HtmlTextWriter(sw);
base.Render(hWriter);
string pageHTML = sb.ToString();
// Write it back to the server
writer.Write(pageHTML);
if (Convert.ToBoolean(this.ViewState["SendEmail"]))
{
string HTML = "";
HTML = "<!DOCTYPE HTML PUBLIC '-//IETF//DTD HTML//EN'>";
HTML += "<html>";
HTML += "<head>";
HTML += "<meta http-equiv='Content-Type'";
HTML += "content='text/html; charset=iso-8859-1'>";
HTML += "<title>Order Information</title>";
HTML += "</head>";
HTML += "<body>";
HTML += "See attachment for information.";
HTML += "</body>";
HTML += "</html>";
MailMessage mail = new MailMessage("from@xxx.com", "to@xxx.com", "Subject", HTML);
mail.IsBodyHtml = true;
string path = @"d:\websites\plate.html";
using (StreamWriter sw11 = File.CreateText(path))
{
sw11.WriteLine(pageHTML);
}
mail.Attachments.Add(new Attachment(path));
SmtpClient client = new SmtpClient("192.168.1.127");
client.Send( mail );
Response.Write("<script>alert('Your information has been sent.')</script>");
this.ViewState["SendEmail"] = false;
}
}
在彻底清理/构建我的解决方案之后,当我按下发送按钮时,会调用此函数,并且通过邮件发送html页面没有问题。但是,如果我再次按下发送按钮,我将收到“System.IO.IOException:进程无法访问文件'd:\ websites \ plate.html',因为它正被另一个进程使用。”当我尝试打开文件时发生错误。怎么了?
答案 0 :(得分:2)
SmtpClient实现了IDisposable,但你没有处理实例。
http://msdn.microsoft.com/en-us/library/system.net.mail.smtpclient.aspx
出于这个原因,它可能会持有该文件。
一般来说,在using
语句中包装实现IDisposable的任何内容都是明智的,除非您有特定的理由(例如,您通过包含IDisposable实例的类显式管理对象生存期)。
我还想提请注意@ DanPichelman关于您使用常量文件名的注释,但此代码可以并行执行在不同的线程上。这将导致输出文件被锁定为超过第一个用户的任何用户,直到代码为第一个用户完成。
答案 1 :(得分:1)
正如Eric指出的那样,您应该在SmtpClient
声明中使用using
- 同上MailMessage
。
但是,你仍然最终没有明显的理由写入文件系统。我强烈建议您使用不要求文件开头的Attachment
构造函数之一。您可以写信至MemoryStream
,然后将其回滚,然后将 提供给Attachment
。
除了其他任何内容之外,这意味着如果多个线程(或进程)尝试同时运行此代码,则不会出现问题。
答案 2 :(得分:-2)
我认为你应该关闭它:
using (StreamWriter sw11 = File.CreateText(path))
{
sw11.WriteLine(pageHTML);
sw11.Flush();
sw11.Close();
}