Programming with FastSender


For increasing mail listing application, FastSender object provides an easy way to enable your application to send email in multiple threadings to obtain the best performance.

How does it work?

FastSender object has an inner threading pool based on MaxThreads count. Firstly, Send or SendByPickup submits email to FastSender mail queue. Secondly threading pool retrieves email from mail queue and send it out. Finally OnSent event informs that the email was sent successfully or unsuccessfully.

No. of worker threads in the threading pool of FastSender object is automatically adjusted based on the actual usage. The maximum no. of worker threads is up to the value of MaxThread property specified.

Secondly, We'll discuss some key points of using FastSender.

Declare FastSender as a member variable

Option Explicit
Private WithEvents m_oFastSender As EASendMailObjLib.FastSender
					
Sub Form_Load()
  Set m_oFastSender = New EASendMailObjLib.FastSender
End Sub

That is because of FastSender object maintains an inner thread pool to send email in background, if it is declared as a temporary variable, the FastSender object instance would be destroyed by Visual Basic before sending email is finished.

Wait for all emails are finished before application exits

After invoking Send method of FastSender successfully, that only means current email was submitted to the inner thread pool. However, you should detect if all emails are sent by the following way.

Private Sub WaitAllTaskFinished()
  Do While m_oFastSender.GetQueuedCount() > 0
    DoEvents
  Loop
    
  Do While Not (m_oFastSender.GetIdleThreads() = m_oFastSender.GetCurrentThreads())
    DoEvents
  Loop
End Sub

Catch result by OnSent event

You should implement OnSent event in your application to get result for each email.

Private Sub m_oFastSender_OnSent(ByVal lRet As Long, _
                                ByVal ErrDesc As String, _
                                ByVal nKey As Long, _
                                ByVal tParam As String, _
                                ByVal SenderAddr As String, _
                                ByVal Recipients As String)
    Dim statusDesc As String
    Dim nIndex As Integer
    
    If lRet = 0 Then
        statusDesc = "sent successfully"
    Else
        statusDesc = ErrDesc
    End If
    
    nIndex = nKey
    g_lSent = g_lSent + 1
End Sub

Using Mail object as the email composer

Const ConnectNormal = 0
Const ConnectSSLAuto = 1
Const ConnectSTARTTLS = 2
Const ConnectDirectSSL = 3
Const ConnectTryTLS = 4
            
Private sub SendEmail()
  Dim recipientAddr(3) As String
  Dim i As Integer
  Dim m_oSmtp As New EASendMailObjLib.Mail
  ' for evaluation usage, please use "TryIt" as the license code.
  m_oSmtp.LicenseCode = "TryIt"
    
  If m_oFastSender Is Nothing  Then
    Set m_oFastSender = New EASendMailObjLib.FastSender
    m_oFastSender.MaxThreads = 10 'set the maximum no. of worker threads
  End If
  
  '  Your SMTP server address.
  m_oSmtp.ServerAddr = "smtp.emailarchitect.net" 

  '  User and password for ESMTP authentication
  m_oSmtp.UserName = "test@emailarchitect.net" 
  m_oSmtp.Password = "testpassword" 

  '  If server supports SSL/TLS connection, SSL/TLS is used automatically.
  m_oSmtp.ConnectType = ConnectTryTLS
        
  m_oSmtp.FromAddr = "test@emailarchitect.net"

  recipientAddr(0) = "test@adminsystem.com"
  recipientAddr(1) = "test1@adminsystem.com"
  recipientAddr(2) = "test2@adminsystem.com"
  
  For i = 0 To 2
    m_oSmtp.ClearRecipient
    m_oSmtp.AddRecipient recipientAddr(i), recipientAddr(i), 0
    m_oSmtp.Subject = "test subject"
    m_oSmtp.BodyText = "test body"

    Call m_oFastSender.Send(m_oSmtp, i, "any")
  Next
  
End Sub

The following code demonstrates how to use FastSender object to send mass emails.

Option Explicit
 
Const ConnectNormal = 0
Const ConnectSSLAuto = 1
Const ConnectSTARTTLS = 2
Const ConnectDirectSSL = 3
Const ConnectTryTLS = 4

Private WithEvents m_oFastSender As EASendMailObjLib.FastSender
Private m_oSmtp As EASendMailObjLib.Mail
 
Private Sub SendEmail()
  Dim recipientAddr(3) As String
  Dim i As Integer
  
  If m_oFastSender Is Nothing Or m_oSmtp Is Nothing Then
    Set m_oFastSender = New EASendMailObjLib.FastSender
    Set m_oSmtp = New EASendMailObjLib.Mail
    ' for evaluation usage, please use "TryIt" as the license code.
    m_oSmtp.LicenseCode = "TryIt"    

    m_oFastSender.MaxThreads = 10 'set the maximum no. of worker threads
  End If
  
  '  Your SMTP server address.
  m_oSmtp.ServerAddr = "smtp.emailarchitect.net" 

  '  User and password for ESMTP authentication
  m_oSmtp.UserName = "test@emailarchitect.net" 
  m_oSmtp.Password = "testpassword" 

  '  If server supports SSL/TLS connection, SSL/TLS is used automatically.
  m_oSmtp.ConnectType = ConnectTryTLS
        
  m_oSmtp.FromAddr = "test@emailarchitect.net"

  recipientAddr(0) = "test@adminsystem.com"
  recipientAddr(1) = "test1@adminsystem.com"
  recipientAddr(2) = "test2@adminsystem.com"
  
  For i = 0 To 2
    m_oSmtp.ClearRecipient
    m_oSmtp.AddRecipient recipientAddr(i), recipientAddr(i), 0
    m_oSmtp.Subject = "test subject"
    m_oSmtp.BodyText = "test body"

    Call m_oFastSender.Send(m_oSmtp, i, "any")
  Next
  
End Sub
 
Private Sub m_oFastSender_OnSent(ByVal lRet As Long, _
                                 ByVal ErrDesc As String, _
                                 ByVal nKey As Long, _ 
                                 ByVal tParam As String,  _
                                 ByVal Sender As String, _ 
                                 ByVal Recipients As String)
  If lRet = 0 Then
    MsgBox nKey & " email was sent successfully"
  Else
    MsgBox nKey & ": " & ErrDesc
  End If
End Sub

How many threads should I use?

Basically, there is no limitation for worker threads count of FastSender, it depends on hardware of your machine. We'v tested it with more than 100 threads on Windows XP C800/256M.

Suggestion for worker threads count:
1.Send email via dnslookup 20-50 threads.
2.Send email via IIS SMTP Service 10 threads.
3.Send email via IIS SMTP Pickup 10 threads

From above code, you will find that FastSender only handles the email sending, you have to use Mail object to set subject, body text and etc... Then Send method passes Mail object to FastSender, FastSender will get the encoded content from Mail object and send it out. Therefore, if you want to change the email content dynamically for each email, you just need to change the properties of Mail object before invoking Send method.

  For i = 0 To 2
    m_oSmtp.ClearRecipient
    m_oSmtp.AddRecipient recipientAddr(i), recipientAddr(i), 0
    m_oSmtp.Subject = "test subject"
    
    'change body text for each email.
    m_oSmtp.BodyText = "Dear" & recipientAddr(i) & "test body" 

    Call m_oFastSender.Send(m_oSmtp, i, "any")
  Next

ASP with FastSender

Because ASP doesn't support event handle, so you can't use FastSender in ASP directly. But the following articles provide the alternative ways to use FastSender with ASP.

Work with EASendMail Service(Mail Queuing)

Total Samples

Please refer to mass.* samples in EASendMail installation package.

Online

Send Bulk Email with Multiple Threads in Visual C++
Send Bulk Email with Multiple Threads in VB6
Send Bulk Email with Multiple Threads in Delphi

See Also

Using EASendMail ActiveX Object
Registration-free COM with Manifest File
User Authentication and SSL Connection
From, ReplyTo, Sender and Return-Path
Digital Signature and Email Encryption - S/MIME
DomainKeys Signature and DKIM Signature
Send Email without SMTP server(DNS lookup)
Work with EASendMail Service(Mail Queuing)
Programming with Asynchronous Mode
Mail vs. FastSender
Bulk Email Sender Guidelines
Process Bounced Email (Non-Delivery Report) and Email Tracking
Work with RTF and Word
EASendMail ActiveX Object References
EASendMail SMTP Component Samples