Send Bulk (Mass) Email in C# and VB.NET
Sending a large number of emails (bulk email) to a group of addresses is typically done for advertising or marketing purposes (e.g., subscription notifications, broadcast advertising, marketing campaigns, etc.).
The following example shows how you can send a large number of email messages using C# or VB.NET code. The emails are sent asynchronously, so that the application isn't blocked or halted, and with multiple threads to improve performance.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using GemBox.Email;
using GemBox.Email.Smtp;
class Program
{
const string Host = "<HOST>";
const string Username = "<USERNAME>";
const string Password = "<PASSWORD>";
const string Sender = "<ADDRESS>";
static int SentEmailCounter = 0;
static void Main()
{
// If using the Professional version, put your serial key below.
ComponentInfo.SetLicense("FREE-LIMITED-KEY");
var mailingList = new List<string>()
{
"first.receiver@example.com",
"second.receiver@example.com",
"third.receiver@example.com",
"..."
};
int chunkSize = 80;
// Split "mailingList" to multiple lists of "chunkSize" size.
var mailingChunks = SplitMany(mailingList, chunkSize);
// Process each "mailingChunks" chunk as a separate Task.
IEnumerable<Task> sendMailingChunks = mailingChunks.Select(
mailingChunk => Task.Run(() => SendEmails(mailingChunk)));
// Create a Task that will complete when emails were sent to all the "mailingList".
Task sendBuilkEmails = Task.WhenAll(sendMailingChunks);
// Displaying the progress of bulk email sending.
while (!sendBuilkEmails.IsCompleted)
{
Console.WriteLine($"{SentEmailCounter,5} emails have been sent!");
Task.Delay(1000).Wait();
}
}
static void SendEmails(IEnumerable<string> recipients)
{
using (var smtp = new SmtpClient(Host))
{
smtp.Connect();
smtp.Authenticate(Username, Password);
foreach (var recipient in recipients)
{
MailMessage message = new MailMessage(Sender, recipient)
{
Subject = "New Blog Post",
BodyText = "Dear reader,\n" +
"We have released a new blog post.\n" +
"You can find it on: https://www.gemboxsoftware.com/company/blog"
};
smtp.SendMessage(message);
Interlocked.Increment(ref SentEmailCounter);
}
}
}
static List<List<string>> SplitMany(List<string> source, int size)
{
var sourceChunks = new List<List<string>>();
for (int i = 0; i < source.Count; i += size)
sourceChunks.Add(source.GetRange(i, Math.Min(size, source.Count - i)));
return sourceChunks;
}
}
Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Threading
Imports System.Threading.Tasks
Imports GemBox.Email
Imports GemBox.Email.Smtp
Module Program
Const Host As String = "<HOST>"
Const Username As String = "<USERNAME>"
Const Password As String = "<PASSWORD>"
Const Sender As String = "<ADDRESS>"
Dim SentEmailCounter As Integer = 0
Sub Main()
' If using the Professional version, put your serial key below.
ComponentInfo.SetLicense("FREE-LIMITED-KEY")
Dim mailingList As New List(Of String)() From
{
"first.receiver@example.com",
"second.receiver@example.com",
"third.receiver@example.com",
"..."
}
Dim chunkSize As Integer = 80
' Split "mailingList" to multiple lists of "chunkSize" size.
Dim mailingChunks = SplitMany(mailingList, chunkSize)
' Process each "mailingChunks" chunk as a separate Task.
Dim sendMailingChunks As IEnumerable(Of Task) = mailingChunks.Select(
Function(mailingChunk) Task.Run(Sub() SendEmails(mailingChunk)))
' Create a Task that will complete when emails were sent to all the "mailingList".
Dim sendBuilkEmails As Task = Task.WhenAll(sendMailingChunks)
' Displaying the progress of bulk email sending.
While Not sendBuilkEmails.IsCompleted
Console.WriteLine($"{SentEmailCounter} emails have been sent!")
Task.Delay(1000).Wait()
End While
End Sub
Sub SendEmails(ByVal recipients As IEnumerable(Of String))
Using smtp As New SmtpClient(Host)
smtp.Connect()
smtp.Authenticate(Username, Password)
For Each recipient In recipients
Dim message As New MailMessage(Sender, recipient) With
{
.Subject = "New Blog Post",
.BodyText = "Dear reader," & vbLf &
"We have released a new blog post." & vbLf &
"You can find it on: https://www.gemboxsoftware.com/company/blog"
}
smtp.SendMessage(message)
Interlocked.Increment(SentEmailCounter)
Next
End Using
End Sub
Function SplitMany(ByVal source As List(Of String), ByVal size As Integer) As List(Of List(Of String))
Dim sourceChunks As New List(Of List(Of String))()
For i As Integer = 0 To source.Count - 1 Step size
sourceChunks.Add(source.GetRange(i, Math.Min(size, source.Count - i)))
Next
Return sourceChunks
End Function
End Module
Task
based asynchronous programming enables you to execute a non-blocking parallel or multi-threaded processing of your mailing list.
A single SmtpClient
object can't send multiple messages simultaneously; instead, it sends emails one by one over the socket being used. To achieve parallel sending, we need multiple SmtpClient
objects and multiple sockets.
It's not advisable to create a new SmtpClient
object for each recipient because connecting with and authenticating on an email server will increase the latency. This is why in the above example the large mailing list is split into a number of smaller ones of the specified size. A new SmtpClient
object is created and used to send bulk email to recipients from each of those smaller mailing lists.
For sending, you can use an SMTP server from a bulk email service or a free email provider. Note that to successfully send mass emails with a free email provider (without having a portion of your messages undelivered, blocked, or moved to a Spam folder), you'll need to follow the provider's Bulk Email Sender Guidelines:
To personalize the messages for each recipient, you can use GemBox.Email's mail merge feature and create multiple personalized email messages based on a single message template and data source.