5 votes

La méthode SmtpClient.SendMailAsync se bloque lors de l'envoi d'un grand nombre de messages.

J'essaie d'envoyer un grand nombre d'emails en utilisant SmtpClient.SendMailAsync méthode. Voici ma méthode de test que j'appelle depuis l'application console simple.

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

Parfois la méthode est suspendue - elle attend de SendMailAsync qui semble bloqué et ne revient pas.

Je vois une question connexe SendMailAsync de SmtpClient n'est parfois jamais retourné . Mais il n'y a pas de solution proposée qui fonctionne pour moi.

Quand j'ai essayé d'utiliser la méthode synchrone SmtpClient.Send tout est OK et l'application ne se bloque jamais.

Quelqu'un a-t-il une idée de ce qui ne va pas ?

1voto

Nkosi Points 95895

Utilisez un seul client pour envoyer les courriers répétés. Le fait de créer et d'éliminer continuellement autant de clients peut entraîner des problèmes de port.

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

Deuxièmement, bien qu'il ne s'agisse probablement que d'un exemple, il est déraisonnable d'essayer d'envoyer autant de courriels en une seule fois.

1voto

Inako Points 115

Un de mes collègues m'a signalé le fait que SmtpClient est en fait obsolète et Microsoft recommande de ne pas l'utiliser.

Voir ce qui suit enlace .

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

J'ai essayé d'utiliser MailKit comme recommandé dans le lien. Le même scénario fonctionne parfaitement avec MailKit pour les deux non asynchrone y asynchrone l'envoi.

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

0voto

tatigo Points 508
  • Pour l'envoi d'un grand nombre d'emails avec SmtpClient, je me souviens qu'il était recommandé de réutiliser la même connexion.
  • Je changerais la façon dont vous gérez l'asynchronisme pour cela. Essayez le ThreadPool .

À titre d'information, SmtpClient ne prend pas en charge les protocoles modernes. Il peut néanmoins être utilisé pour les courriels occasionnels, pour des usages internes et des tests.
Vous pouvez essayer MailKit

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X