Reputation: 2132
I have a following method which I call for every MailMessage:
public static string SendEmail(MailMessage email)
{
string rez = "";
try
{
var smtpserver = "10.xxx.xx.xx";
using (SmtpClient mailclient = new SmtpClient())
{
mailclient.Host = smtpserver;
mailclient.Send(email);
}
rez = "OK";
}
catch (Exception ex)
{
rez = "NOT OK: " + ex.Message;
}
return rez;
}
I send 32 email-s at once, and for two of them I got following error from mailclient.Send(): NOT OK: Service not available, closing transmission channel. The server response was: 4.3.2 The maximum number of concurrent connections has exceeded a limit, closing transmission channel
I was wondering if this is because I created a new SmtpClient instance for every mail?
Will the following change fix the problem since there is only one instance of SmtpClient. UnfortunatellyI cannot test it, I can only try it in production.
public static SmtpClient mailclient = new SmtpClient("10.xxx.xx.xx");
public static string SendEmail(MailMessage email)
{
string rez = "";
try
{
mailclient.Send(email);
rez = "OK";
}
catch (Exception ex)
{
rez = "NOT OK: " + ex.Message;
}
return rez;
}
Thanks.
Upvotes: 1
Views: 17177
Reputation: 856
I could not find a way to limit the SMTPClient to a certain number of connections, and I came upon this question trying to track that down. I found a way to send multiple emails at the same time from different threads and have them stack up and run through a shared SMTPClient which uses one connection, releasing the next message to send using an AutoResetEvent.
See my answer on Stack Overflow here. in a related question.
Upvotes: 0
Reputation: 35544
You can reuse the instance of the SmtpClient to send emails and it is good practice (see MSDN), but i think it will not solve your problem.
From MSDN
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. Also many email client applications support an off-line mode where users can compose many email messages that are sent later when a connection to the SMTP server is established. It is typical for an email client to send all SMTP messages to a specific SMTP server (provided by the Internet service provider) that then forwards this email to other SMTP servers.
The SmtpClient class implementation pools SMTP connections so that it can avoid the overhead of re-establishing a connection for every message to the same server. An application may re-use the same SmtpClient object to send many different emails to the same SMTP server and to many different SMTP servers. As a result, there is no way to determine when an application is finished using the SmtpClient object and it should be cleaned up.
When an SMTP session is finished and the client wishes to terminate the connection, it must send a QUIT message to the server to indicate that it has no more messages to send. This allows the server to free up resources associated with the connection from the client and process the messages which were sent by the client.
The SmtpClient class has no Finalize method, so an application must call Dispose to explicitly free up resources. The Dispose method iterates through all established connections to the SMTP server specified in the Host property and sends a QUIT message followed by gracefully ending the TCP connection. The Dispose method also releases the unmanaged resources used by the Socket and optionally disposes of the managed resources. Call Dispose when you are finished using the SmtpClient. The Dispose method leaves the SmtpClient in an unusable state. After calling Dispose, you must release all references to the SmtpClient so the garbage collector can reclaim the memory that the SmtpClient was occupying.
Upvotes: 5