Search code examples
c#async-awaitamazon-sesmailkitmimekit

Sending bulk emails with MailKit using a throttle fails with a delay of 10 seconds or more


I am using a loop to send bulk emails via MailKit with an added throttle (delay). The idea is that I intend to send a limit of 20 individual emails per second to multiple recipients. To throttle the sends, I have added a Task.Delay (e.g. int delay = 1000 / 20 ) inside the loop.

We are using an ESP with 40 sends per second (AWS SES), so it is definitely not the SMTP server.

This seems to work well except when I tried testing it with a delay of 10 seconds or more. I stress, I'm testing only.

Here is my test sender:

    protected void Send( )
    {
        var messages = new List<MimeMessage>( );

        for( int i = 1; i < 4; i++ )
        {
            var message = new MimeMessage
            {
                Sender = new MailboxAddress( "Sender Name", "Sender Email Address" ),
                Subject = "Test email " + i.ToString( ),
                Body = new TextPart( TextFormat.Html ) { Text = "Test body " + i.ToString( ) }
            };
            message.To.Add( new MailboxAddress( "test" + i.ToString( ) + "@example.com" ) );
            messages.Add( message );
        }

        MailNew.SendMultipleAsyncMails( messages );
    }

Here is the sender code:

    public static void SendMultipleAsyncMails( List<MimeMessage> messages )
    {
        Task t = Task.Run( async ( ) =>
        {
            using( var client = new SmtpClient( ) )
            {
                await client.ConnectAsync( "Host", 587, SecureSocketOptions.StartTls );
                await client.AuthenticateAsync( "UserName", "Password" );
                foreach( var message in messages )
                {
                    await client.SendAsync( message );
                    await Task.Delay( 10000 );
                }
                await client.DisconnectAsync( true );
            }
        } );
    }

What happens is it throws an exception of: 'MailKit.Net.Smtp.SmtpCommandException' in mscorlib.dll after the first send if there is a delay of 10 seconds or more. I can't see why this should make a difference.

Realistically, you would never add a delay of 10 seconds or more to this process, but I am asking out of curiosity as to why it does this and to confirm that I have not missed anything important.

Can anyone work out why a 10+ second delay will fail?


Solution

  • Okay, found the issue. It's AWS SES. The email server responded with the following error code:

    451 Timeout waiting for data from client Too much time elapsed between requests, so the SMTP server closed the connection.

    This now makes sense as to why there was no exception in the code, but it's interesting that application continued to run as if there was no issue.

    The only way to trace this error was to use the protocol log as suggested by @jstedfast