Question:
How can I determine which email message the Mailman event OnPercentDone is referring to?
While sending a quantity of emails, I need to move the files attached to each email once the email has been sent. However I can't figure how to deduce which email has been sent from the OnPercentDone event.
Grateful for any pointers you can give me.
Public Class frmSendEmails
Me.BGW_Email = New System.ComponentModel.BackgroundWorker()
Me.BGW_Email.WorkerReportsProgress = True
Me.BGW_Email.WorkerSupportsCancellation = True
.
.
.
Private qEmails As New Queue(Of String)
Private WithEvents mailman As New Chilkat.MailMan()
Private Sub btn_Email_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_Email.Click
me.BGW_Email.RunWorkerAsync()
End Sub
Private Sub BGW_EMail_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BGW_Email.DoWork
Dim di As DirectoryInfo
Dim fi As FileInfo
Dim fiArr As FileInfo()
Dim sFolder, sEmail As String
Dim email As Chilkat.Email
mailman.EnableEvents = True
mailman.SmtpPort = 25
mailman.SmtpHost = "localhost"
For Each fi In fiArr
If BGW_Email.CancellationPending Then
Throw New Exception("******** User cancelled ********")
e.Cancel = True
Exit Sub
End If
sEmail = fnGetEmailFromFile(fi.fullname)
email = New Chilkat.Email()
email.Subject = dctEmailConfig.Item("EMAIL_SUBJECT")
email.Body = dctEmailConfig.Item("EMAIL_BODY")
email.From = dctEmailConfig.Item("EMAIL_FROM")
email.AddCC(dctEmailConfig.Item("EMAIL_CC"), dctEmailConfig.Item("EMAIL_FROM"))
email.AddTo(sEmail, sEmail)
mailman.SendEmail(email)
bResult = mailman.SendEmail(email)
If bResult Then
SyncLock qEmails
qEmails.Enqueue(fi.FullName)
End SyncLock
End If
Next fi
end sub
Private Sub mailman_OnPercentDone(ByVal sender As Object, ByVal args As Chilkat.PercentDoneEventArgs) Handles mailman.OnPercentDone
Dim sDestFolder, sFile As String
If (args.PercentDone = 100) Then
SyncLock qEmails
sFile = qEmails.Peek()
sDestFolder = Path.GetDirectoryName(sFile) & "\Sent"
System.IO.File.Move(sFile, sDestFolder)
qEmails.Dequeue()
End SyncLock
End If
End Sub
End Class
The class "frmSendEmails" contains a single instance of Chilkat.MailMan. Therefore, the "mailman" object can only be sending a single email at a time. When sending email, the Chilkat.MailMan is connected to the SMTP server and the connection is stateful. (See http://www.cknotes.com/?p=40 )
It wouldn't make sense for multiple threads to be attempting to communicate over the same connection to send email at the same time -- because they would interfere with each other. The communications for sending an email have to proceed through an orderly step-by-step process. Once one email is sent, another may begin on the existing connection. However, two emails cannot be sent simultaneously on the same connection. (In general, this applies to all Internet protocols that are stateful: FTP, HTTP, IMAP, POP3, etc. SSH is potentially a bit different because the protocol itself allows for logical channels within the connection.)
Back to your code snippet: It allows multiple threads to attempt to send email simultaneously using the same mailman object instance, but the Chilkat.MailMan is thread-safe, which means that it prevents bad things from happening. It cannot allow simultaneous mail-sending, so when SendEmail is called, another thread's call to SendEmail will be blocked until the current thread's SendEmail returns. At which point the next thread may enter SendEmail, etc.
Therefore, to truly have multiple threads sending email at the same time, you would want each thread to have its own mailman object. If that is the case, then the "sender" in "Private Sub mailman_OnPercentDone(ByVal sender As Object" indicates the mailman object doing the sending.