C # list <Stream> dispose / close

I set up a subscription service to send reports to various people in our company on a schedule. I plan to send reports by email, the reporting system that I use can export as a PDF stream (rather than writing temporary files). Most people will get more than one report, so I'm trying to attach them to one email, doing something like

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

What I'm not sure if I should erase and close the stream immediately after adding it to the list, will this be normal? Or do I need to loop the list after that to clear and destroy? I am trying to avoid a memory leak that is possible.

+4
source share
5 answers

Why not create a StreamCollection class that implements IDisposable:

 public class StreamCollection : Collection<Stream>, IDisposable { } 

In the Dispose method of this class, you can skip all threads and properly close / delete each thread. Then your code will look like this:

 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); } 
+18
source

You can create a DisposableList that can be placed in a using statement:

 public class DisposableList<T> : List<T>, IDisposable where T : IDisposable { // any constructors you need... public void Dispose() { foreach (T obj in this) { obj.Dispose(); } } } 
+3
source

Depends on whether streams will be used later when creating the attachment. I assume this means that you want to get rid of the threads at the end.

Do not forget to try - finally, this. Otherwise, they will not be deleted if an exception occurs.

+1
source

I do not see the logic of closing threads immediately after adding it to the list. Based on the code you provided, it appears, links to these streams are used elsewhere. If the threads are closed, what good are they serving?

+1
source

There is no harm in executing Flush () / Close (). If you want to be absolutely sure, you should make an instruction using :

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

Thus, exceptions will not affect your code.

0
source

All Articles