简体   繁体   中英

C# Sending a large number of emails using System.Net.Mail

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();
 }

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.

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();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM