简体   繁体   English

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

[英]SmtpClient: The maximum number of concurrent connections has exceeded a limit

I have a following method which I call for every MailMessage: 我有一个以下方法,我为每个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. 我一次发送32封电子邮件,其中两封我从mailclient.Send()收到以下错误: 不行:服务不可用,关闭传输通道。 The server response was: 4.3.2 The maximum number of concurrent connections has exceeded a limit, closing transmission channel 服务器响应为:4.3.2最大并发连接数已超过限制,关闭传输通道

I was wondering if this is because I created a new SmtpClient instance for every mail? 我想知道这是因为我为每封邮件创建了一个新的SmtpClient实例吗?

Will the following change fix the problem since there is only one instance of SmtpClient. 以下更改是否会解决问题,因为只有一个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. 谢谢。

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. 您可以重用SmtpClient的实例来发送电子邮件,这是一个很好的做法(请参阅MSDN ),但我认为它不会解决您的问题。

From MSDN 来自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. 如果应用程序希望将多个消息发送到同一SMTP服务器,则可以重新使用由SmtpClient类的当前实例建立到SMTP服务器的连接。 This is particularly useful when authentication or encryption are used establish a connection to the SMTP server. 当使用身份验证或加密建立与SMTP服务器的连接时,这尤其有用。 The process of authenticating and establishing a TLS session can be expensive operations. 验证和建立TLS会话的过程可能是昂贵的操作。 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. 在向同一SMTP服务器发送大量电子邮件时重新建立每条消息的连接的要求可能会对性能产生重大影响。 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. 此外,许多电子邮件客户端应用程序支持离线模式,用户可以撰写许多电子邮件,这些邮件将在以后建立与SMTP服务器的连接时发送。 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. 通常,电子邮件客户端将所有SMTP邮件发送到特定的SMTP服务器(由Internet服务提供商提供),然后将此电子邮件转发到其他SMTP服务器。

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. SmtpClient类实现汇集了SMTP连接,因此可以避免为同一服务器的每条消息重新建立连接的开销。 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. 应用程序可能会重复使用相同的SmtpClient对象将许多不同的电子邮件发送到同一SMTP服务器和许多不同的SMTP服务器。 As a result, there is no way to determine when an application is finished using the SmtpClient object and it should be cleaned up. 因此,无法确定何时使用SmtpClient对象完成应用程序,并且应该清除它。

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. 当SMTP会话结束并且客户端希望终止连接时,它必须向服务器发送QUIT消息以指示它没有更多要发送的消息。 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. SmtpClient类没有Finalize方法,因此应用程序必须调用Dispose以显式释放资源。 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. Dispose方法遍历所有已建立的与Host属性中指定的SMTP服务器的连接,并发送QUIT消息,然后正常结束TCP连接。 The Dispose method also releases the unmanaged resources used by the Socket and optionally disposes of the managed resources. Dispose方法还释放Socket使用的非托管资源,并可选择处理托管资源。 Call Dispose when you are finished using the SmtpClient. 使用完SmtpClient后调用Dispose。 The Dispose method leaves the SmtpClient in an unusable state. Dispose方法使SmtpClient处于不可用状态。 After calling Dispose, you must release all references to the SmtpClient so the garbage collector can reclaim the memory that the SmtpClient was occupying. 在调用Dispose之后,必须释放对SmtpClient的所有引用,以便垃圾收集器可以回收SmtpClient占用的内存。

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

See my answer on Stack Overflow here. 请在此处查看我对Stack Overflow的回答 in a related question. 在一个相关的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM