Inako
Inako

Reputation: 389

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

I am trying to send a lot of emails to using SmtpClient.SendMailAsync method. Here is my test method that I call from the simple console application.

    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);
            }
        }
    }

Sometimes the method is hanging - it awaits to SendMailAsync which seems stuck and doesn't return.

I see one related question SmtpClient SendMailAsync sometimes never returns . But there is no fix suggested that works for me.

When I tried to use the synchronous method SmtpClient.Send everything is OK and application never hangs.

Does anybody have any idea what is wrong?

Upvotes: 7

Views: 4302

Answers (3)

Inako
Inako

Reputation: 389

One on my colleague pointed me to the fact that SmtpClient is actually obsolete and Microsoft recommends not to use it.

See the following link.

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

I have tried to use MailKit as recommended in the link. The same scenario is working perfectly with MailKit for both non async and async sending.

   **********************************

Upvotes: 3

tatigo
tatigo

Reputation: 2254

  • For sending large number of emails with SmtpClient I remember that it was recommended to reuse the same connection.
  • I would change the way how you handle async for this. Try the ThreadPool.

As a side note, SmtpClient doesn't support modern protocols. It's still ok to use for the occasional email for internal uses and tests.
You can try MailKit

Upvotes: 0

Nkosi
Nkosi

Reputation: 246998

Use one client to send the repeated mails. Continuously creating and disposing that many clients can have port issues.

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);
            }
        }
    }
}

Secondly, though probably just as this is an example, its is unreasonable to try and send that many emails in one go.

Upvotes: 2

Related Questions