Send Email Asynchronously (Programming with Asynchronous Mode)


In this section, We'll discuss the key points of asynchronous mode of Mail object.

In synchronous mode, once SendMail method of Mail object is called, it returns to application after the method is complete. Therefore, if the runtime(it depends on the newworking connection and the email size) is long, your application cannot do anything before this method ends, which results "my application is blocked or halted". In contrast, in asynchronous mode, as SendMail method works in background, this methods return to application immediately no matter the running method is complete or not. The return value will pass to application via fired event.

Both of synchronous mode and asynchronous mode of Mail have the same performance. The difference is your application can do other thing while sending email with asynchronouse mode. Notice that ASP doesn't support event handle, so asynchronous mode can't be used in ASP.

How to implement asynchronous mode? We'll demonstrate it with Visual Basic.

First of all, you should add a reference of EASendMail into your project. Please click here to learn how to add reference of EASendMail to your current project. Then you MUST declare Mail object as a member variable like this.

Option Explicit
Private WithEvents m_oSmtp As EASendMailObjLib.Mail
					
Sub Form_Load()
  Set m_oSmtp = New EASendMailObjLib.Mail
  m_oSmtp.Asynchronous = 1
End Sub

Why it MUST be declared as a member variable?

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

Handle the events.

Secondly, you should add the following implementation in your code to handle the event fired by Mail object.

Private Sub m_oSmtp_OnAuthenticated()
	'Add your implementation code
End Sub

Private Sub m_oSmtp_OnClosed()
	'Add your implementation code
End Sub

Private Sub m_oSmtp_OnConnected()
	'Add your implementation code
End Sub

Private Sub m_oSmtp_OnError(ByVal lError As Long, _ 
    ByVal ErrDescription As String)
	'Add your implementation code
End Sub

Private Sub m_oSmtp_OnSending(ByVal lSent As Long, _
    ByVal lTotal As Long) 
	'Add your implementation code
End Sub

Then you can use the following code to send an email.

m_oSmtp.Reset
m_oSmtp.ServerAddr = "mail.adminsystem.net"
m_oSmtp.FromAddr = "test@adminsystem.net"
m_oSmtp.AddRecipient "Support Team", "support@adminsystem.net", 0

m_oSmtp.Subject = "Test"
m_oSmtp.BodyText = "Hello, this is a test...."
 
m_oSmtp.SendMail

How do I know if this email is sent successfully in asynchronous mode.

Because you can't use return value of SendMail method to detect if the current email is sent successfully. So you need to use the OnError event and OnClose event to get the result. In short, if OnClose event was fired but OnError was not fired, that means the email was sent successfully.

Option Explicit
Private WithEvents m_oSmtp As EASendMailObjLib.Mail
Private m_bErr As Boolean	
Private m_errStr As String			
					
Sub Form_Load()
  Set m_oSmtp = New  EASendMailObjLib.Mail
  m_oSmtp.Asynchronous = 1
'The license code for EASendMail ActiveX Object,
  'for evaluation usage, please use "TryIt" as the license code.
  m_oSmtp.LicenseCode = "TryIt"  
End Sub

Sub SendEmail
  m_oSmtp.Reset
  m_oSmtp.ServerAddr = "mail.adminsystem.net"
  m_oSmtp.FromAddr = "test@adminsystem.net"
  m_oSmtp.AddRecipient "Support Team", "support@adminsystem.net", 0

  m_oSmtp.Subject = "Test"
  m_oSmtp.BodyText = "Hello, this is a test...."
 
  m_bErr = False
  m_errStr = ""
  m_oSmtp.SendMail
End Sub

Private Sub m_oSmtp_OnClosed()
  If m_bErr Then
    MsgBox m_errStr
  Else
    MsgBox "Message delivered!"
  End If
End Sub

Private Sub m_oSmtp_OnError(ByVal lError As Integer, _ 
    ByVal ErrDescription As String)
  m_errStr = ErrDescription
  m_bErr = True
End Sub

Note*: You SHOULD NOT invoke SendMail method any more while EASendMail is sending an email, otherwise the email of sending would be terminated automatically. The following code demonstrate how to send multiple emails with Mail object in asynchronous mode.

Option Explicit
Private WithEvents m_oSmtp As  EASendMailObjLib.Mail
Private m_bIdle	'idle flag
					
Sub Form_Load()
  Set m_oSmtp = New  EASendMailObjLib.Mail
  m_oSmtp.Asynchronous = 1
  m_bIdle = True
End Sub

Sub SendEmail
  Dim arRcpts
  arRcpts = Array( "support@adminsystem.net", "ivan@adminsystem.net" )
  
  Dim i, nCount
  nCount = UBound(arRcpts)
  For i = LBound(arRcpts) To nCount
    m_oSmtp.Reset
    m_oSmtp.ServerAddr = "mail.adminsystem.net"
    m_oSmtp.FromAddr = "test@adminsystem.net"
    m_oSmtp.AddRecipient arRcpts(i), arRcpts(i), 0
    m_oSmtp.Subject = "Test"
    m_oSmtp.BodyText = "Hello, this is a test...."
    m_bIdle = False 'set flag to busy
    m_oSmtp.SendMail
    
    Do While(Not m_bIdle)' waiting while current email is sending.
      DoEvents
    Loop
  Next
End Sub

Private Sub m_oSmtp_OnClosed()
  m_bIdle = True
End Sub

Private Sub m_oSmtp_OnError(ByVal lError As Integer, _ 
    ByVal ErrDescription As String)
  m_bIdle = True
End Sub

To learn more about asynchronous mode, please refer to rich samples in EASendMail installation package.

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 FastSender
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

Online Tutorials

Send Email in VB 6.0 - Tutorial
Send Email in Visual C++ - Tutorial
Send Email in Delphi - Tutorial
Send Email in MS SQL stored procedure - Tutorial