我正在设置订阅服务,以便按计划向我们公司的各个人发送报告。我打算通过电子邮件发送报告,我正在使用的报告系统能够导出为PDF流(而不是编写临时文件)。大多数人会收到多个报告,所以我试图将它们全部附加到一封电子邮件中,例如
List<Stream> reports = new List<Stream>();
//looping code for each users set of reports
Stream stream = ReportSource.ReportDocument.ExportToStream(PortableDocFormat)
reports.Add(stream);
stream.Flush(); //unsure
stream.Close(); //unsure
//end looping code
SmtpClient smtpClient = new SmtpClient(host, port);
MailMessage message = new MailMessage(from, to, subject, body);
foreach (Stream report in reports)
{
message.Attachments.Add(new Attachment(report, "application/pdf"));
}
smtpClient.Send(message);
我不确定的是,在将其添加到列表中后,我是否应该刷新并关闭流,这样可以吗?或者我之后是否需要循环列表以进行刷新和处理?我试图避免任何可能的内存泄漏。
答案 0 :(得分:20)
为什么不创建一个实现IDisposable的StreamCollection类:
public class StreamCollection : Collection<Stream>, IDisposable { }
在该类的Dispose方法中,您可以遍历所有流并正确关闭/处理每个流。然后你的代码看起来像:
using (var reports = new StreamCollection())
{
//looping code for each users set of reports
reports.Add(ReportSource.ReportDocument.ExportToStream(PortableDocFormat));
//end looping codeSmtpClient
smtpClient = new SmtpClient(host, port);
MailMessage message = new MailMessage(from, to, subject, body);
foreach (Stream report in reports)
{
message.Attachments.Add(new Attachment(report, "application/pdf"));
}
smtpClient.Send(message);
}
答案 1 :(得分:4)
您可以创建一个可以包装在using语句中的DisposableList:
public class DisposableList<T> : List<T>, IDisposable where T : IDisposable {
// any constructors you need...
public void Dispose() {
foreach (T obj in this) {
obj.Dispose();
}
}
}
答案 2 :(得分:1)
取决于以后是否在创建附件时使用流。我认为它们意味着你最终会想要处理这些流。
记得尝试 - 最后这个。否则,如果发生异常,他们不会被处置。
答案 3 :(得分:1)
在将列添加到列表后,我没有看到关闭流的逻辑。根据您提供的代码,可以看到对这些流的引用正在其他地方使用。如果溪流关闭,那么它们有什么用处?
答案 4 :(得分:0)
在执行Flush()/ Close()时没有任何伤害。如果您想完全确定,那么您应该使用使用语句:
using (Stream stream = ReportSource.ReportDocument.ExportToStream(PortableDocFormat))
{
reports.Add(stream);
stream.Flush(); //unsure
}
这样,异常不会影响您的代码。