bgregs
bgregs

Reputation: 166

Why Doesn't SMTP Mail Attachment Dispose When Client Does?

This is an issue that I recently solved, but was wondering if somebody could help clear this up for me since I don't fully understand what exactly happened. I created a simple smtp email client and wrapped it in a using statement to dispose of it. Inside the email I added a PDF file attachment which I had generated on the fly. Once the email was sent, I wanted to destroy the PDF since it was temporarily saved locally on the machine in order to send the email. When the File.Delete() method would run, I would get the error that the IIS Worker Process was locking the file. I couldn't understand why since my client was already disposed of before I tried to delete the file. Finally I found out that I had to dispose of the attachment as well before I could delete the file. So, my question is why doesn't disposing of the client also dispose of the attachment as well? Isn't the attachment part of the client so therefore it should be disposed of once the client is disposed? Sample code below:

try
    {
        using (SmtpClient SmtpMail = new SmtpClient(""))
        {
            MailMessage message = new MailMessage(From, To, Subject, Body);
            message.IsBodyHtml = false;
            message.Priority = MailPriority.Normal;
            Attachment attachment = new Attachment(pdfString);
            message.Attachments.Add(attachment);
            SmtpMail.Send(message);
            attachment.Dispose(); //Why is this needed?
        }
    }

Upvotes: 1

Views: 2153

Answers (1)

medkg15
medkg15

Reputation: 1595

The SmtpClient's Send() method isn't (and shouldn't be) responsible for disposing of the MailMessage (and its associated assets). The SmtpClient cannot make an assumption about your intended usage of the MailMessage after it has been sent. You may wish to continue using the MailMessage or attachment stream to do other things.

Let's consider the case where a MailMessage instance will be re-used by multiple SmtpClients.

var message = new MailMessage();

using(var client1 = new SmtpClient())
{
    client1.Send(message);
}

...

using(var client2 = new SmtpClient())
{
    client2.Send(message);
}

If the message's attachments had already been disposed after the first call, the second call would fail.

It would be incorrect for the SmtpClient to just assume that you're done with the MailMessage after the first time you send it. The Send() method should send an email, not send and also dispose of the message assets. Your program may have had a need to do further work with the Attachment stream later in the program.

Upvotes: 10

Related Questions