views:

895

answers:

1

I'm looking for good performance when sending a lot of e-mails.

I have heard that the right way to do it is to open a connection send ~20 e-mails and close the connection. And do that over and over again. Is this correct?

And how does SmtpClient work, does it open a connection for it's own lifetime? (not IDisposable, so doesn't look like that) Or does it open a connection for each e-mail being sent? Or does it have a connection open all the time? Or does it have some magic that opens and closes connections when it's appropriate?

I would like to know so I know how I should initiate the SmtpClient. As a singleton or only for a chunk of messages...

+3  A: 

Hi,

It only sends a single MailMessage from a connection. In fact, it doesn't even properly close the connection. It sends the mail, but then it doesn't tell the mail server it wants to quit. So, it just leaves it hanging open, until the underlying pooled stream decides to close the socket.

Here is the internal code from Reflector:

...
        this.GetConnection();
        fileMailWriter = this.transport.SendMail((message.Sender != null) ? message.Sender : message.From, recipients, message.BuildDeliveryStatusNotificationString(), out exception);
        }
        catch (Exception exception2)
        {
            if (Logging.On)
            {
                Logging.Exception(Logging.Web, this, "Send", exception2);
            }
            if ((exception2 is SmtpFailedRecipientException) && !((SmtpFailedRecipientException) exception2).fatal)
            {
                throw;
            }
            this.Abort();
            if (this.timedOut)
            {
                throw new SmtpException(SR.GetString("net_timeout"));
            }
            if (((exception2 is SecurityException) || (exception2 is AuthenticationException)) || (exception2 is SmtpException))
            {
                throw;
            }
            throw new SmtpException(SR.GetString("SmtpSendMailFailure"), exception2);
        }

btw, here is more info about the SmtpClient not issuing the QUIT command. https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=146711&wa=wsignin1.0

The work-around is to set SmtpClient.ServicePoint.MaxTimeout to 1. This will close the socket faster, however, this doesn't actually issue the QUIT command.

Cheers!

Dave

dave wanta