I like many developers am tasked with creating batch emails to send to a large population of users. And for this I am not talking about spam, I am referring to sending emails to a large poplulation within an organization such as annual notification reminders or custom links to some application. I have tried sending these emails synchroniously and if you are sending a few hundred that isn't a problem, but when I started sending several thousand, I was noticing a bottleneck with my SMTP server and waiting for the callback showing the SMTP server receved the message.
So moving forward from that thought the best option for sending mass emails greater than a few hundred is using threading and asynchronious sending. I have tried this a few different ways in the past with event listeners and different techniques, but moving to the async and await world of modern .Net I thought I would re-write it with some more modern tooling. Since this took me a little trial and error I thought it would be a good thing to post for my fellow developers out there.
From a performance standpoint using the same SMTP server I was getting about three emails per second with standard synchronous methods and when I went to the attached code, I went up to about 18 (running locally over VPN to our corporate offices) and I will expect to see an even bigger jump on a VM in the datacenter. Overall there isn't much impact to performance on the machine with minimal CPU and RAM overhead.
Anyway, click here to get to my code.
Two things I want to point out:
- I know I have a weird try / catch in there. That is because the mail server was choking with that many emails going through at one time and I was getting random errors. Retrying one time usually fixed it.
- I know there are async methods with the SMTP client, but when you use that it still only allows one email to be processed at a time by the general SMTP client thus making it an async method but not async in the since that I wanted which was mass emails with threading.