Sending many unique emails at same time I have an asp.net core app that sends emails with a link. When they click the link they can start taking an online test without logging in. The link contains a number that is validated by the controller who then returns their test.

I log into my app and create a project. Here I enter a list of emails in a textbox separated by commas. In the backend I put this textbox string into a list like so:

string emailList;
List&lt;string&gt; list = emailList.Split(',').ToList();
//removes whitespace in list:
for (int i = 0; i &lt; list.Count(); i++)
{
 list[i] = string.Join("", list[i].Split(default(string[]), 
                       StringSplitOptions.RemoveEmptyEntries));
}


The only way i can see on how to send many unique emails would be to loop over this list and then use the normal SendEmail method in mimekit:

string message = "Press this link to take the test";
int number = 0;

foreach(var email in emailList)
{
  //gets a unique number stored in a table for each person:
  number = GetNumber(email);      
  message = $"http://www.mywebsite.com/Test/{number}";
  await _emailSender.SendEmailAsync(email, "Subject", message);
}


Now the emailSender uses the normal mimekit method to send one email for each in the list.

This takes a long time for a big list. Are there any other ways to do it, or can I write this more effectively? What could be the bottlenecks of my solution? Any feedback would be great, from my bad async code to security . I suspect that I use too much async when I should return only a task, but i'm not sure how to do it. I also wonder how I can even test this on a larger scale as I don't have a big emaillist to use.

Here is the mimekit code to send the email:

public async Task SendEmailAsync(string email, string subject, string message)
{
  var melding = new MimeMessage();
  melding.From.Add(new MailboxAddress("Frank", _options.Option1));
  melding.To.Add(new MailboxAddress(email));
  melding.Subject = subject;

  melding.Body = new TextPart("plain")
  {
     Text = message
  };
  Try
  {
     await SendMessage(melding);
  }
  catch(Exception ex)
  {
     //log error
     throw new ApplicationException($"something went wrong:'{ex.Message}'.");
  }
}
private async Task SendMessage(MimeMessage message)
{
   using (var client = new SmtpClient())
   {
      await client.ConnectAsync("smtp.WebSiteLive.net", 587, SecureSocketOptions.None);
      client.AuthenticationMechanisms.Remove("XOAUTH2"); // Must be removed for Gmail SMTP
      await client.AuthenticateAsync(_options.Option1, _options.Option2);
      await client.SendAsync(message);
      await client.DisconnectAsync(true);
    }            
}


any help much apprechiated!!
using (var client = new SmtpClient())
   {
      await client.ConnectAsync("smtp.WebSiteLive.net", 587, SecureSocketOptions.None);
      client.AuthenticationMechanisms.Remove("XOAUTH2"); // Must be removed for Gmail SMTP
      await client.AuthenticateAsync(_options.Option1, _options.Option2);
      ...
      await client.DisconnectAsync(true);
    }            



Look at how much work you're doing per message. If you reuse the client, you save setup and teardown time on every message after the first one.

If you reuse the client then you'll need to handle errors and be prepared to close it, open a new one, and continue where you left off; so there is a speed-complexity trade-off.