I'm using the following code to send an email asynchronously. It's usually through gmail. It works fine but occasionally there is a collision with an IMAP check of the email account or a follow up SMTP async send. The attacments can get to 10-25 mbs which takes a minute or two to upload. I'm trying to prevent those collisions by incorporating a global variable 'MailSendInProgress' It gets set to TRUE just before the asyncsend and to FALSE in the callback from the async. I also use it as a check during some IMAP operations elsewhere in the application as this is what seemed to interfere and cause an error in the async email sending process. My question is whether there is a better way to accomplish this. This process seems to work OK but it feels hokey and maybe will cause problems in the future? Thanks for any thoughts you might have!
Check to prevent collisions from IMAP or other SMTP send operations:
If MailSendInprogress Then Exit Sub
Public MailSendInprogress As Boolean = Falsepublic sub SendMail() Try Dim SmtpServer As New SmtpClient() AddHandler SmtpServer.SendCompleted, AddressOf SendCompletedCallback Dim mail As New MailMessage() SmtpServer.Credentials = New Net.NetworkCredential(strMailLogin, strMailPassword) SmtpServer.Port = 587 SmtpServer.EnableSsl = True SmtpServer.Host = strSMTPServer mail = New MailMessage() mail.From = New MailAddress(strMailLogin) If strAttachments = "YES" Then Dim attachment As System.Net.Mail.Attachment Using attachment attachment = New System.Net.Mail.Attachment(Application.StartupPath & "\") mail.Attachments.Add(attachment) attachment = New System.Net.Mail.Attachment(Application.StartupPath & "\") mail.Attachments.Add(attachment) attachment = New System.Net.Mail.Attachment(Application.StartupPath & "\") mail.Attachments.Add(attachment) attachment = New System.Net.Mail.Attachment(Application.StartupPath & "\") mail.Attachments.Add(attachment) End Using End If mail.To.Add(strTo) mail.Subject = strSubject mail.Body = strBody If IsHTML Then mail.IsBodyHtml = True Do Until MailSendInprogress = False Thread.Sleep(1000) Loop MailSendInprogress = True SmtpServer.SendAsync(mail, Nothing) LogIt("**** MAIL SENT *****") Catch ex As Exception LogIt("ERROR Sending email!" & ex.StackTrace) End Try Private Sub SendCompletedCallback(sender As Object, e As AsyncCompletedEventArgs) ' Throw New NotImplementedException Try If e.Error IsNot Nothing Then LogIt("ERROR SENDING ASYNC EMAIL: " & e.Error.ToString) Else LogIt("ASYNC EMAIL SEND COMPLETED.") End If Catch ex As Exception LogIt("ERROR " & ex.ToString) End Try MailSendInprogress = False End Sub
If you are concerned about multiple hits to same process or method, then you can use lock statement. It is reffered as SyncLock in VB.net. Furthermore you may not need MailSendInprogress to track status of SendMail.
You may find following articles helpful:
Open in new window