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?
我听说正确的方法是打开一个连接发送20封电子邮件并关闭连接。一遍又一遍。这是正确的吗?
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?
SmtpClient是如何工作的,它是否为自己的生命打开了一个连接?(不是i可支配的,所以看起来不是那样的)或者它是否为发送的每封电子邮件打开一个连接?还是一直都有连接打开?或者它有什么魔法可以在适当的时候打开和关闭连接?
I would like to know so I know how I should initiate the SmtpClient. As a singleton or only for a chunk of messages...
我很想知道,所以我知道应该如何开始SmtpClient。作为一个单例,或者仅为一个消息块……
1 个解决方案
#1
7
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:
这是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
顺便说一下,这里有更多关于SmtpClient不发出退出命令的信息。https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=146711&wa=wsignin1.0
Edit: View the dead link above on web.archive.org
编辑:在web.archive.org上查看上面的死链接
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.
解决方法是设置SmtpClient.ServicePoint。MaxTimeout 1。这将更快地关闭套接字,然而,这实际上并不发出退出命令。
#1
7
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:
这是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
顺便说一下,这里有更多关于SmtpClient不发出退出命令的信息。https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=146711&wa=wsignin1.0
Edit: View the dead link above on web.archive.org
编辑:在web.archive.org上查看上面的死链接
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.
解决方法是设置SmtpClient.ServicePoint。MaxTimeout 1。这将更快地关闭套接字,然而,这实际上并不发出退出命令。