Is it ok to instantiate a SMTP client once and send 2,000 emails on it synchronously?
We are getting the following error, when instantiating a SMTP client for every message we send using the code also pasted at end of this post:
System.Net.Mail.SmtpException: Service not available, closing transmission channel. The server response was: 4.4.1 Connection timed out
I am suspecting that instantiating SMTP client for every message is causing this but not sure. Code is as below.
List<MailMessage> messages = GetMailMessages();
foreach( MailMessags m in messages)
{
try
{
SmtpClient client = new SmtpClient();//SHOULD THIS BE PLACED OUTSIDE AND BEFORE THE LOOP
client.Send(m);
}
catch (Exception)
{
throw;
}
}
EDIT 1:
I just found this on MSDN. (http://msdn.microsoft.com/en-us/library/ee706942%28v=vs.110%29.aspx). So it seems the lesson is when using mass emailing, you must instantiate the SMTP client only once and re-use it for all multiple MailMessages.
The connection established by the current instance of the SmtpClient class to the SMTP server may be re-used if an application wishes to send multiple messages to the same SMTP server. This is
particularly useful when authentication or encryption are used establish a connection to the SMTP server. The process of authenticating and establishing a TLS session can be expensive operations. A requirement to re-establish a connection for each message when sending a large quantity of email to the same SMTP server could have a significant impact on performance. There are a number of high-volume email applications that send email status updates, newsletter distributions, or email alerts.
You should really be kinder to your mail server but SMTP client can handle more than one email and you'd get better use of your servers hardware if you did this asynchronously like so ...
async Task SendMail(ICollection<MailMessage> messages)
{
using (var client = new SmtpClient())
{
foreach (MailMessags m in messages)
{
try
{
await client.SendAsync(m);
}
catch (Exception)
{
throw;
}
}
}
}
I suspect the reason for the exception being thrown at the moment is due to repeated connection attempts, so the server maybe "acting out" as a means to say "stop poking me with repeated connections".
The code sample above will determine how many connections to make on your behalf and communicate more "politely" with the server, also as you have pointed out, the documentation points at a few other scenarios in which this approach is better suited to.
来源:https://stackoverflow.com/questions/21894671/sending-2000-emails