0

We have an ASP.NET MVC application that sends a number of reports via e-mail to clients each month. Each e-mail attaches a monthly statement. Currently we have around 70 clients but this will hopefully increase over time. We have been seeing issues that a number of e-mails are not getting sent. We use the System.Net.Mail API.

Here is the code we are using, is there a better approach?

 foreach(string client in clients){

    SmtpClient client = new SmtpClient("server.com");

    BackgroundWorker emailInvoker = new BackgroundWorker();
    emailInvoker.DoWork += delegate
    {
      // Delay to prevent flow control, try later Relay error
      Thread.Sleep(TimeSpan.FromSeconds(2));
      client.Send(message);
    }

   emailInvoker.RunWorkerAsync();
 }
Steven V
  • 16,357
  • 3
  • 63
  • 76
user327999
  • 443
  • 1
  • 9
  • 21
  • 4
    To be honest, and I know this is off topic, I would be more concerned about being black listed or tarpitting on your mail sever. Any way, you haven't given any indication of why the message isn't being sent (any error message/crashes etc) – Dave Mar 21 '13 at 15:35
  • 1
    The `BackgroundWorker` is possibly redundant as you can use `SmtpClient.SendAsync` to send the e-mail asynchronously anyhow. What kind of errors are you seeing in the event log etc? – Lloyd Mar 21 '13 at 15:37
  • It would be much easier, less painful, more reliable, and cheaper to use a third party service such as SendGrid to send your emails. This will let you focus on your core business instead of the mundane task of sending emails. – TWA Mar 21 '13 at 18:08

2 Answers2

1

We have been seeing issues that a number of e-mails are not getting sent.

The larger (and more likely) problem than some of them aren't getting sent is that many of them are not getting delivered.

...is there a better approach?

In most cases. Jeff Atwood goes over many of the problems with sending email in this blog post. That post was almost 3 years ago and even then, the first comment recommends using postmark. I've used postmark and it reliably handles the problem of getting your emails out through code at a good price. That said, there are better solutions on the market now, the one my company is currently very tempted to switch to is mandrill. Slightly better pricing, awesome analytics.

marr75
  • 5,666
  • 1
  • 27
  • 41
0

Because this is an ASP.NET MVC application, you need to be aware of your application pool. Creating multiple threads will exhaust your app pool quickly, and IIS maybe doing some funky things to keep things from literally grinding to a halt while emails are being sent. I would take a look at Can I use threads to carry out long-running jobs on IIS? if you're interested on learning more.

If I were to rewrite that, I would create one thread with the foreach and email sending, instead of a thread for each customer.

 BackgroundWorker emailInvoker = new BackgroundWorker();

 emailInvoker.DoWork += delegate
 {
     // get your clients here somehow

     foreach(string client in clients){

         SmtpClient client = new SmtpClient("server.com");

         // Delay to prevent flow control, try later Relay error
         Thread.Sleep(TimeSpan.FromSeconds(2));
         client.Send(message);
     }
 }

 emailInvoker.RunWorkerAsync();
Community
  • 1
  • 1
Steven V
  • 16,357
  • 3
  • 63
  • 76