SmtpClient:最大并发连接数超过了限制

问题描述 投票:1回答:2

我有一个以下方法,我为每个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;
        }

我一次发送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;
            }

谢谢。

c# smtpclient
2个回答
3
投票

您可以重复使用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占用的内存。


0
投票

我找不到一种方法将SMTPClient限制为一定数量的连接,我发现这个问题试图跟踪它。我找到了一种从不同线程同时发送多封电子邮件的方法,让它们堆叠起来并通过使用一个连接的共享SMTPClient运行,释放下一条要使用AutoResetEvent发送的消息。

在相关问题中查看我对Stack Overflow here.的回答。

© www.soinside.com 2019 - 2024. All rights reserved.