SmtpClient.SendMailAsync 发送大量邮件时方法挂起

SmtpClient.SendMailAsync method is hanging when sending a big amount of mails

我正在尝试使用 SmtpClient.SendMailAsync 方法发送大量电子邮件。 这是我从简单控制台应用程序调用的测试方法。

    static void Main(string[] args)
    {

        SendMailsOnebyOneAsync().GetAwaiter().GetResult();

    }


    public static async Task SendMailsOnebyOneAsync()
    {
        for (int i = 0; i < 1000; i++)
        {
            try
            {
                using (SmtpClient sMail = new SmtpClient("XXX"))
                {
                    sMail.DeliveryMethod = SmtpDeliveryMethod.Network;
                    sMail.UseDefaultCredentials = false;
                    sMail.Credentials = null;

                    var fromMailAddress = new MailAddress("XXX");
                    var toMailAddress = new MailAddress("XXX");

                    MailMessage message = new MailMessage(fromMailAddress, toMailAddress)
                    {
                        Subject = "test"
                    };

                    await sMail.SendMailAsync(message);

                    Console.WriteLine("Sent {0}", i);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }
    }

有时该方法会挂起 - 它等待 SendMailAsync,这似乎卡住了但没有 return。

我看到一个相关问题 SmtpClient SendMailAsync sometimes never returns。 但是没有建议对我有用的修复方法。

当我尝试使用同步方法时 SmtpClient.Send 一切正常,应用程序永远不会挂起。

有人知道哪里出了问题吗?

使用一个客户端发送重复的邮件。不断创建和处理许多客户端可能有端口问题。

public static async Task SendMailsOnebyOneAsync() {
    using (var sMail = new SmtpClient("XXX")) {
        sMail.DeliveryMethod = SmtpDeliveryMethod.Network;
        sMail.UseDefaultCredentials = false;
        sMail.Credentials = null;

        for (int i = 0; i < 1000; i++) {
            try {
                var fromMailAddress = new MailAddress("XXX");
                var toMailAddress = new MailAddress("XXX");

                var message = new MailMessage(fromMailAddress, toMailAddress) {
                    Subject = "test"
                };

                await sMail.SendMailAsync(message);

                Console.WriteLine("Sent {0}", i);
            } catch (Exception e) {
                Console.WriteLine(e.Message);
            }
        }
    }
}

其次,虽然这可能只是一个例子,但尝试一次发送那么多电子邮件是不合理的。

我的一位同事向我指出 SmtpClient 实际上已经过时,Microsoft 建议不要使用它。

见下文link.

     ************ Update ***********

我已经尝试按照 link 中的建议使用 MailKit。 对于 non asyncasync 发送,相同的场景与 MailKit 完美配合。

   **********************************
  • 对于使用 SmtpClient 发送大量电子邮件,我记得建议重复使用相同的连接。
  • 我会改变你处理异步的方式。试试 ThreadPool.

附带说明一下,SmtpClient 不支持现代协议。 偶尔用于内部使用和测试的电子邮件仍然可以。
你可以试试 MailKit