2

I maintain the website for a small organization with roughly 100 to 120 members.

Every month, we send out an email notifying our members of the topics we will cover in the upcoming meetings.

I am trying to use our website to give us a way to send these emails out, but our ASP Hosting Site has a defined limit of 50 emails per hour.

Theoretically, I suppose I could put the thread to sleep for 1-minute after each SmtpClient.Send(MailMessage) call by using a Thread.Sleep(60000), like this:

public const int ONE_MINUTE = 60000;

public String SiteEmailAddress { get; set; }
public String SiteMailServer { get; set; }
public String SiteMailUserId { get; set; }
public String SiteMailPwd { get; set; }

public void BulkEmail(String emailMessage) {
    using (var msg = new MailMessage()) {
        msg.From = new MailAddress(SiteMailAddress);
        msg.Body = emailMessage;
        msg.DeliveryNotificationOptions = DeliveryNotificationOptions.OnFailure;
        using (var server = new SmtpClient(SiteMailServer, 25)) {
            server.Credentials = new NetworkCredential(SiteMailUserId, SiteMailPwd);
            foreach (var person in Personnel.GetActiveMembers()) {
                var msgTo = person.PersonalEmail;
                if (!String.IsNullOrEmpty(msgTo)) {
                    msg.To.Clear();
                    msg.To.Add(new MailAddress(msgTo, person.FullName));
                    server.Send(msg);
                    System.Threading.Thread.Sleep(ONE_MINUTE);
                }
            }
        }
    }
}

That would either make our website appear dead for over an hour while this ran or it would likely fail.

What is a simple solution for doing this?

  • Spam prevention measures taken by major email providers are very likely to flag messages from an unknown domain as spam. You're much better off using a 3rd party provider for mass mailings – Jason Watkins Mar 24 '16 at 21:41
  • 3
    Instead if clearing `msg.To` in your loop, add all your receipents and send a single email.... – Eser Mar 24 '16 at 21:43

5 Answers5

2

Don't use your web server to send emails.

Let a mail sending API handle it for you. This isn't the place to recommend a specific product, so I won't.


If you are going to trickle emails out through your web server, don't do it on the web thread. Store your email-sending status in the database and send one at a time, do it on a separate thread, or use a separate app.

Jacob Krall
  • 28,341
  • 6
  • 66
  • 76
  • I was pretty sure my technique was wrong, but I've never tried it or seen it done before. I welcome links to **mail sending API**, but it is a non-profit veteran's organization. I'm already paying for the website out of my own pocket. –  Mar 24 '16 at 21:51
  • 1
    SendGrid and Mailgun both have free tiers for users who send up to about 10000 emails per month. – Jacob Krall Mar 24 '16 at 21:58
  • I signed up for a Mailgun account and updated my Domain settings. It'll take a couple of days before it kicks in, though. So, will my normal emails on my hosted domain still work, or is Mailgun going to take over all of it? I didn't see a way to get the free account with SendGrid. –  Mar 24 '16 at 23:02
2

Based on your case I would suggest some solutions:
1- Schedule a task to run every 1.2 min for example, and this task will call the email sender method, and not need to use the Sleep.
Example of how to schedule tasks in asp.net website: http://www.hanselman.com/blog/HowToRunBackgroundTasksInASPNET.aspx
Best way to run scheduled tasks
http://hangfire.io/

2- Add a new task in the windows task scheduler manually or using code (if your hosting allow this), and make this task to call a page in your website which sends the email.

3- Create a separate application in a separate thread which handle the email sending process without affecting your main website performance (this could be a windows service, console app, or normal windows app).

Community
  • 1
  • 1
Amr Elgarhy
  • 66,568
  • 69
  • 184
  • 301
1

If you're determined to send the emails from your web server, you can use Background Tasks in ASP.NET. Scott Hanselman did a nice write up about it.. You could have it process 50 at a time then wait the remainder of the hour before continuing or wait 72 seconds between each email so that you're sending at most 50 an hour.

Babak Naffas
  • 12,395
  • 3
  • 34
  • 49
0

We use sendgrid to send emails for our site it has a free monthly limit of 12,000 https://sendgrid.com/free might be an easier alternative?

Macilquham
  • 282
  • 1
  • 10
  • That sounds like a good plan, but this is for a non-profit veteran's group. I am paying for the website out of my own pocket as it is now. Their most basic package is $10/month for 40,000 emails. That is 100 times more volume than we could ever use. –  Mar 24 '16 at 21:54
  • If 40,000 is 100x more than you need, the 12,000 offered in the free package should be sufficient for your 400 emails. – dub stylee Mar 24 '16 at 22:43
0

First of all creating background thread and put it to sleep does not kill application in any way. It will just take thread from thread pool and lock it till operation complete and than dispose it.

Though this can be issue on high traffic applications and limited thread pool, where multiple requests must be handled on same time. Another thing to consider is with each application shutdown, this task get canceled if running. But if that is not issue for you and you want a simple solution, that is.

I would recommend rather use of external API to let it handle for you.

Ľuboš Pilka
  • 1,044
  • 1
  • 11
  • 17