必须手动关闭Usings中的StreamWriter
本文关键字:Usings 中的 StreamWriter | 更新日期: 2023-09-27 17:59:41
在第二次迭代中,"正在使用的文件"错误出现在"using(StreamWriter)"行。即使StreamWriter应该在退出using后自动关闭自己。
编辑1:真实代码
注意:邮件是一个List<MailMessage>
(用From/To地址实例化)
foreach (var x in mails)
{
x.Subject = "Updated Google Exchange Rates (" +
DateTime.Now.ToString(new CultureInfo("en-US")) +
")";
StringBuilder emailBody = new StringBuilder();
emailBody.AppendLine("abc"); //<-- simplified
x.Body = emailBody.ToString();
_txtName = x.Subject.Replace(...); //Replaces invalid file-name chars
//Note that _txtName will always be unique due to x.Subject's dependency on DateTime
using (StreamWriter sw = new StreamWriter("./Exchange Rate History/" + _txtName))
{
sw.WriteLine(emailBody);
sw.Close();
}
Attachment attachment = new Attachment("./Exchange Rate History/" + _txtName);
attachment.Name = _txtName;
x.Attachments.Add(attachment);
SmtpClient smtpClient = new SmtpClient("...")
{
Credentials = new System.Net.NetworkCredential("", ""),
Port = 25
};
smtpClient.Send(x);
smtpClient.Dispose();
}
我必须在"usings"结束之前添加"sw.Close();"At才能使这个循环工作。为什么?
第2版:哦,不!sw。Close()停止工作!"正在使用的文件"。
发现问题,不是StreamWriter在usings
之后没有关闭自己。
Chris Sinclair关于DateTime
不保证唯一文件名的说法是正确的。如果你的for循环很短(因此很快),你可能会得到重复的名字,这就是我的情况。
对于5封电子邮件,_txtName
生成了5个相同的文件名,这意味着我最终得到了一个文件,因为StreamWriter默认情况下会覆盖。
此外,我忘记在每个循环结束时使用x.Attachments.Dispose();
。因此,当它重新迭代时,x.Attachments.add()
仍在尝试附加相同的文件(上传时间),而StreamWriter
开始写入相同的文件,因为DateTime
比for循环慢,导致_txtName
生成了重复的名称。
TL;DR:for循环太快太激烈了。