lockedscope
lockedscope

Reputation: 983

Sending multiple async emails

I want to send multiple emails asynchronously. Emails do not depend on each other and no code will run after emails send, so i want to fire multiple and forget. I am following this article for sending async emails but i am not sure if i am doing the right thing for sending multiple emails.

A few of my concerns;

public class MyController : Controller
{
    public async Task SendEmailAsync(IdentityMessage message)
    {
        var mailMessage = new MailMessage
            ("[email protected]", message.Destination, message.Subject, message.Body);
        using(var client = new SmtpClient())
        {
            await client.SendMailAsync(mailMessage);
        }
    }

    public ActionResult Create()
    {
        Action<CancellationToken> workItem = SendEmails;
        HostingEnvironment.QueueBackgroundWorkItem(workItem);

        return View();
    }

    private async void SendEmails(CancellationToken cancellationToken)
    {
        await SendEmailAsync(new IdentityMessage(...));
        await SendEmailAsync(new IdentityMessage(...));
   }
}

Upvotes: 0

Views: 2751

Answers (1)

Sergii Apostol
Sergii Apostol

Reputation: 311

In SendEmails every next email is waiting for completion of previous, you should rewrite it like this:

private async Task SendEmails(CancellationToken cancellationToken)
{
        await Task.WhenAll(SendEmailAsync(new IdentityMessage(...)),
                           SendEmailAsync(new IdentityMessage(...)));
}

By doing so all email will be send in parallel. Also you should not QueueBackgroundWorkItem in Create. You can just do next:

 public async Task<ActionResult> Create()
 {
        HostingEnvironment.QueueBackgroundWorkItem(async (token)=> await SendEmails() );

        return View();
 }

But please keep in mind that if any exception occur in SendEmails you will not be notified about this. Let me know if this can be an issue for you, so i will provide solution for this.

But i prefer another approach of sending emails from web application. It is more complicated but more reliable. Web app should never send messages to smtp server but store request to queue or db. Than we have background application that listen to queue and every time new request was detected it try to send it to smtp. if attempt fail system will return request back to the queue and will try few more times later. This background app may be windows service of webjob if your app is hosted in azure. Advantages of this approach:

  1. no UI thread blocking - to put something in queue is short running operation
  2. even if smtp server is not accessible for some period of time you are sure that all emails will be delivered

Disadvantages:

  1. You have to maintain additional component of your system

Upvotes: 1

Related Questions