I cannot use using
inside the loop because then I won't be able to send email because cannot access a closed stream
.
I cannot using(MemoryStream memoryStream = new MemoryStream()){the rest of the codes}
because then only first excel will have data, the rest will be empty with file size of 64 B. I already verify that all excel have data before send it via email.
foreach (workbook excel in workbooks)
{
MemoryStream memoryStream = new MemoryStream();
excel.hssfWorkBook.Write(memoryStream);
memoryStream.Position = 0;
mailMessage.Attachments.Add(new Attachment(memoryStream, excel.fileName, "application/vnd.ms-excel"));
}
smtpClient.Send(mailMessage);
There is no need to close this memory stream.
You just need to make sure your mailMessage
is disposed properly. Once it is disposed, all attachments are disposed as well, and therefore their Streams
.
Look at MailMessage
source code here and search Dispose()
implementation:
public void Dispose()
{
Dispose(true);
}
protected virtual void Dispose(bool disposing)
{
if (disposing && !disposed)
{
disposed = true;
if(views != null){
views.Dispose();
}
if(attachments != null){
attachments.Dispose();
}
if(bodyView != null){
bodyView.Dispose();
}
}
}
To dispose your mailMessage, just use using
like this simple example:
using (var mailMessage = new MailMessage())
{
using (var smtpClient = new SmtpClient())
{
foreach (workbook excel in workbooks)
{
MemoryStream memoryStream = new MemoryStream();
excel.hssfWorkBook.Write(memoryStream);
memoryStream.Position = 0;
mailMessage.Attachments.Add(new Attachment(memoryStream, excel.fileName, "application/vnd.ms-excel"));
}
smtpClient.Send(mailMessage);
}
}