Don’t make your users wait unnecessarily. For example, a page where you generate a PDF and send it to someone else. Hand the job off to an asynchronous process and move on.
There are a lot of ways this can be done, but the easiest seems to be using a Thread. However, you run into a problem with having parameters. A parameterizedThread can actually only have ONE parameter…. but it can be an object, so that means you can jam all sorts of cool things in there.
Here is a example of a parameterized thread
First, you make a nice class to hold your parameters:
Public mTo As String
Public mFrom As String
Public subject As String
Public body As String
Public attachmentMemoryStream As MemoryStream
Public attachmentFileName As String
Public archiveFile As String
Then we have a subroutine attached to a button that does a fire-and-forget email. Basically, it just says, “send that..” and continues to process the page. You get refreshed practically instantly.
protected sub btnSendMail_OnClick(sender as object, e as eventargs) handles btnSendMail.click
Dim objMailParams As New mailParams
objMailParams.mTo = strTo
objMailParams.mFrom = strFrom
objMailParams.subject = strSubject
objMailParams.body = strMessage
Dim asyncMailObj As New System.Threading.ParameterizedThreadStart(AddressOf sendAnEmail)
Dim t As New System.Threading.Thread(asyncMailObj)
That ParameterizedThreadStart simply assigns a CPU thread to kick off the subroutine “sendAnEmail”. I preloaded the class of parameters and used the entire class as a single object parameter.
sub sendAnEmail(obj as object)
Dim mp As mailParams = obj
‘=== I keep all my settings for mail and connection strings in a class called DataLayer.
Dim myServer As New DataLayer.mailSettings
Dim objMM As New MailMessage
Dim objSMTP As New SmtpClient
Dim m As New MailMessage()
Dim mTo As New System.Net.Mail.MailAddress(mp.mTo)
Dim mFrom As New System.Net.Mail.MailAddress(mp.mFrom)
objMM.From = mFrom
objMM.IsBodyHtml = False
objMM.Priority = MailPriority.Normal
objMM.Subject = mp.subject
objMM.Body = mp.body
objSMTP.Host = myServer.smtpServer
objSMTP.DeliveryMethod = SmtpDeliveryMethod.Network
objSMTP.Credentials = New System.Net.NetworkCredential(myServer.smtpUser, myServer.smtpPassword)
objSMTP.EnableSsl = False
Now, this is a very simple example. The reason I started doing this is because I was generating PDF invoices by screen captures, then sending an archive of the PDF up to Amazon’s S3 storage, then emailing the pdf to the client. Some of the invoices were 20 pages long. The server can handle the workload, but people couldn’t handle the wait. So, fire-and-forget.
Later on, if it becomes a problem, I’ll see about putting in some kind of confirmation emails that say whether or not the invoice actually got sent.
If it becomes a server memory issue, I’ll update this post with whatever solution I came up with next!