使用SmtpClient发送邮件的最佳方式是什么?

5

我希望在发送大量电子邮件时能够获得良好的性能。

我听说正确的做法是打开一个连接,发送约20封电子邮件,然后关闭连接。并且一遍又一遍地重复这个过程。 这是正确的吗?

SmtpClient是如何工作的?它会为其整个生命周期打开一个连接吗?(不是IDisposable,所以看起来不像) 还是每次发送电子邮件都会打开一个连接? 或者它一直保持连接打开状态? 或者它有一些神奇的功能,在适当的时候打开和关闭连接?

我想知道这些信息,以便我知道如何初始化SmtpClient。作为单例还是仅针对一批消息...

1个回答

7

它只使用一个连接发送一封邮件。事实上,它甚至没有正确关闭连接。它发送了邮件,但是它没有告诉邮件服务器它想要退出。因此,它只是让连接一直打开着,直到底层池化流决定关闭套接字。

以下是来自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);
        }

顺便提一下,这里有关于SmtpClient未发出QUIT命令的更多信息。 https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=146711&wa=wsignin1.0

编辑:可以在web.archive.org上查看上面的失效链接。

解决方法是将SmtpClient.ServicePoint.MaxTimeout设置为1。这将更快地关闭套接字,但实际上并没有发出QUIT命令。


新的.NET框架中是否已经修复了“QUIT”的问题? - jocull
这个问题据说在.NET 4.0中已经修复了。https://dev59.com/BUnSa4cB1Zd3GeqPOXw7?noredirect=1#comment79406662_1466572 - jocull

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接