2009-12-04 35 views
4

我正在设置订阅服务,以便按计划向我们公司的不同人员发送报告。我计划通过电子邮件发送报告,我正在使用的报告系统可以导出为PDF流(而不是写入临时文件)。什么我不确定是我应该冲洗,并关闭流只是将它添加到列表中后,大多数人会收到不止一个报告,所以我想他们都附加到一个电子邮件做这样的事情C#列表<Stream>处理/关闭

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

这会好吗?或者我需要循环列表后冲洗和处置?我试图避免任何可能的内存泄漏。

回答

18

为什么不创建一个实现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); 
} 
+0

pwetty! +1。 15chars – Quibblesome 2009-12-04 17:06:10

+1

您可以使StreamCollection通用,然后它可以用于任何IDisposable对象 – thecoop 2009-12-04 17:07:08

+0

就像这种方法将使用它 – PeteT 2009-12-05 16:32:41

0

在做Flush()/ Close()时没有任何伤害。如果你想成为绝对的把握,那么你应该做一个使用声明:

using (Stream stream = ReportSource.ReportDocument.ExportToStream(PortableDocFormat)) 
{ 
    reports.Add(stream); 
    stream.Flush(); //unsure 
} 

这样,例外不会影响你的代码。

1

取决于创建附件时以后是否使用流。我认为他们是这意味着你会想在最后处置流。

记得试试这个。否则,如果发生异常,他们不会被处置。

+0

我刚要离开的代码简单的例子,知道做尝试finallys和所有。 – PeteT 2009-12-04 16:35:19

1

我没有看到添加到列表中后关闭流的逻辑。根据您提供的代码,似乎这些流的引用正在其他地方使用。如果溪流已经关闭,那么它们有什么好处呢?

3

您可以创建一个DisposableList,你可以在一个using语句包装:

public class DisposableList<T> : List<T>, IDisposable where T : IDisposable { 

    // any constructors you need... 

    public void Dispose() { 
     foreach (T obj in this) { 
      obj.Dispose(); 
     } 
    } 
}