SmtpClient:最大并发连接数已超出限制

vld*_*jcc 1 c# smtpclient

我有一个为每个 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;
        }
Run Code Online (Sandbox Code Playgroud)

我一次发送 32 封电子邮件,对于其中两封,我从 mailclient.Send() 收到以下错误: 不正常:服务不可用,正在关闭传输通道。服务器响应为: 4.3.2 最大并发连接数已超出限制,关闭传输通道

我想知道这是否是因为我为每封邮件创建了一个新的 SmtpClient 实例?

由于只有一个 SmtpClient 实例,以下更改是否可以解决该问题。不幸的是我无法测试它,我只能在生产中尝试它。

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;
            }
Run Code Online (Sandbox Code Playgroud)

谢谢。

Jeh*_*hof 5

您可以重用 SmtpClient 的实例来发送电子邮件,这是一个很好的做法(请参阅MSDN),但我认为它不能解决您的问题。

来自MSDN

如果应用程序希望向同一 SMTP 服务器发送多条消息,则可以重新使用 SmtpClient 类的当前实例与 SMTP 服务器建立的连接。当使用身份验证或加密建立与 SMTP 服务器的连接时,这特别有用。验证和建立 TLS 会话的过程可能是昂贵的操作。将大量电子邮件发送到同一 SMTP 服务器时,要求为每封邮件重新建立连接可能会对性能产生重大影响。有许多大容量电子邮件应用程序可以发送电子邮件状态更新、新闻通讯分发或电子邮件警报。此外,许多电子邮件客户端应用程序支持离线模式,用户可以在其中撰写许多电子邮件,并在建立与 SMTP 服务器的连接后发送这些电子邮件。电子邮件客户端通常将所有 SMTP 消息发送到特定的 SMTP 服务器(由 Internet 服务提供商提供),然后由该服务器将此电子邮件转发到其他 SMTP 服务器。

SmtpClient 类实现对 SMTP 连接进行池化,这样就可以避免为每条消息重新建立到同一服务器的连接的开销。应用程序可以重复使用相同的 SmtpClient 对象将许多不同的电子邮件发送到相同的 SMTP 服务器和许多不同的 SMTP 服务器。因此,无法确定应用程序何时完成使用 SmtpClient 对象并应将其清理。

当 SMTP 会话完成并且客户端希望终止连接时,它必须向服务器发送 QUIT 消息以表明它没有更多消息要发送。这允许服务器释放与客户端连接相关的资源并处理客户端发送的消息。

SmtpClient 类没有 Finalize 方法,因此应用程序必须调用 Dispose 来显式释放资源。Dispose 方法循环访问所有已建立的到 Host 属性中指定的 SMTP 服务器的连接,并发送一条 QUIT 消息,然后正常结束 TCP 连接。Dispose 方法还释放 Socket 使用的非托管资源,并可以选择处置托管资源。使用完 SmtpClient 后调用 Dispose。Dispose 方法使 SmtpClient 处于不可用状态。调用 Dispose 后,必须释放对 SmtpClient 的所有引用,以便垃圾收集器可以回收 SmtpClient 占用的内存。