必须手动关闭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()停止工作!"正在使用的文件"。

必须手动关闭Usings中的StreamWriter

发现问题,不是StreamWriter在usings之后没有关闭自己。

Chris Sinclair关于DateTime不保证唯一文件名的说法是正确的。如果你的for循环很短(因此很快),你可能会得到重复的名字,这就是我的情况。

对于5封电子邮件,_txtName生成了5个相同的文件名,这意味着我最终得到了一个文件,因为StreamWriter默认情况下会覆盖。

此外,我忘记在每个循环结束时使用x.Attachments.Dispose();。因此,当它重新迭代时,x.Attachments.add()仍在尝试附加相同的文件(上传时间),而StreamWriter开始写入相同的文件,因为DateTime比for循环慢,导致_txtName生成了重复的名称。

TL;DR:for循环太快太激烈了。