JensB
JensB

Reputation: 6850

Threads for slow operations in MVC App

When new users register on my site I require them to verify their email by sending them an email with a unique link in it.

If I do this synchronously with the Controller Register Action it takes about 3 - 5 seconds for the page to return as the email method takes some time to complete.

In order to deal with this I am doing this:

Thread emailRequestThread = new Thread(() => (new EmailSender()).SendConfirmAdressEmail(user));
emailRequestThread.Start();

It is working but is this a bad idea? If so how should I accomplish the same result?

Upvotes: 1

Views: 98

Answers (1)

Yuval Itzchakov
Yuval Itzchakov

Reputation: 149518

Instead of spinning up a new Thread to send mail, i would go with the async approach. What we do here is wrap the StmpClient.SendAsync EAP pattern with a Task so we can await using its TaskAwaitable:

public static Task SendAsyncTask(this SmtpClient client, MailMessage message)
{
   TaskCompletionSource<object> tcs = new TaskCompletionSource<object>();
   Guid sendGuid = Guid.NewGuid();

   SendCompletedEventHandler handler = null;
   handler = (o, ea) =>
   {
      if (ea.UserState is Guid && ((Guid)ea.UserState) == sendGuid)
      {
         client.SendCompleted -= handler;
         if (ea.Cancelled)
         {
            tcs.SetCanceled();
         }
         else if (ea.Error != null)
         {
            tcs.SetException(ea.Error);
         }
         else
         {
            tcs.SetResult(null);
         }
      }
   };

   client.SendCompleted += handler;
   client.SendAsync(message, sendGuid);
   return tcs.Task;
}

And then use it this way:

Task sendTask = await client.SendAsyncTask(message);

Upvotes: 2

Related Questions