I have some code to add attachments to an email. I’m adding them via the Stream overload of the Attachment class constructor. The code to do it looks like this:
List<UploadedDocument> docs = DataBroker.GetUploadedDocs(Convert.ToInt32(HttpContext.Current.Session["offer_id"].ToString()));
//no need to keep this in session
HttpContext.Current.Session["offer_id"] = null;
int counter = 1;
foreach (UploadedDocument doc in docs)
{
stream = new MemoryStream(doc.doc);
attach = new Attachment(stream, "Attachment-" + counter.ToString());
message.Attachments.Add(attach);
}
Where doc.doc is a byte array. I want to properly dispose of each attachment and stream, but I can’t do it until the message has been sent, so I was thinking about just adding them to a List<Attachment> and List<Stream> and then iterating through and calling dispose.
Something like this:
List<Attachment> attachments;
List<Stream> streams;
//...
foreach(UploadedDocument doc in docs)
{
stream = new MemoryStream(doc.doc);
streams.Add(stream);
attach = new Attachment(stream,"Name");
attachments.Add(attach);
message.Attachments.Add(attach);
}
//other processing
emailClient.Send(message);
if(attachments != null)
{
foreach(Attachment attachment in attachments)
{
attachment.Dispose();
}
}
if(streams != null)
{
foreach(MemoryStream myStream in streams)
{
myStream.Dispose();
}
}
But something tells me that won’t dispose them properly if there is still a reference floating around that hasn’t gotten garbage collected or something. Any thoughts?
The simplest way to handle this is to just call
Dispose()on theMailMessage.MailMessage.Disposewill automatically dispose all attachments, which in turn will close/Dispose()all of the underlying streams.