boyersnet

Our family, our website
Welcome to boyersnet Sign in | Join | Help
in Search

Chuck's Blog

Asynchronous Progress With Telerik Upload Control

The application I work on has a built in email newsletter engine and has been experiencing some performance issues when processing large email subscription lists.  As a result we have upgraded it from classic ASP 3.0 to ASP.NET to take advantage of asynchronous processing.  As a part of that asynchronous processing we wanted to show the user a progress bar detailing the progress of their job.  Enter the r.a.d.Upload control by Telerik.  This control comes with a built in progress manager that allows you to monitor the progress of any custom process. 

When the user has finished composing their email newsletter they have several options on sending their message.  I'll focus on the "final" send to the entire list.  When the user clicks "Send Now" the email editor screen hands things over to our pleaseWait page.  This is the page that is hosting the progress manager.  From what I could determine from the help documentation, the Progress Manager requires the hosting page (pleaseWait) fire a PostBack through a server control capable of firing a postback.  The documentation recommends an asp:button control.  In our particular case we didn't want the user to have to press another button just to start their job so in steps document.form.submit in a javascript function in the html. 

  <script language="javascript" type="text/javascript">
   function submitForm() {
     document.Form1.submit();
    }
  </script>

That's great you say, but how do I fire the javascript function if there is no user interaction.  Well, I attached it in the code behind to the body tag in the onload event.  From here we experienced some odd behavior because once the form is submitted, the page_load event is called and the page re-rendered, guess what, the form.submit is called again.  Ooops Chuck, you just sent 2 (or more) emails to everyone on the list.  That won't bode well for your SPAM ratings.  The answer?  Remove the onload event in the case of a postback. 


 Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

  If Page.IsPostBack Then
   body.Attributes.Remove("onload")
   ProcessJob()
  Else
   body.Attributes.Add("onload", "onLoad=submitForm();")
  End If
 End Sub


As you can see, if the page.IsPostback property is set to true, we process the job.  I'm using asynchronous processing so I need a delegate for my business layer object method at the pleaseWait page class level.


'delgate sub for the send function of the mail.sender object
Delegate Sub SendToListHandler()


In the process job method I'm using the basic asychrnous princiapals of using BeginInvoke, checking to see if the asynchronous result IsComplete property is true, then calling end invoke to release the process.

'create the delegate object and bind to the target method
Dim SendHandler As SendToListHandler
SendHandler = AddressOf message.SendtoList

'execute method asynchronously and capture the IAsyncResult object
Dim ar As System.IAsyncResult
ar = SendHandler.BeginInvoke(Nothing, Nothing)

Do While (Not ar.IsCompleted)

 'update the progress
 If totalRecipients > 0 Then
  UpdateProgress("send", messageId)
 Else
  totalRecipients = message.TotalRecipients
 End If
Loop

Try
 SendHandler.EndInvoke(ar)
Catch ex As Exception
End Try

As you probably have noticed, I'm looping to see if the ar.IsCompleted is true.  If it isn't, then I'm updating the ProgressManager using my UpdateProgress method shown here:

Private Sub UpdateProgress(ByVal Action As String, ByVal MessageId As Integer)

 Dim progress As Telerik.WebControls.RadProgressContext = Telerik.WebControls.RadProgressContext.Current

 Dim sentCount As Integer = 0
 Dim percentComplete As Integer
 Dim loopCount As Integer = 0

 Try

  Do While sentCount <= totalRecipients

   If Action = "send" And (loopCount Mod 10 = 0) Then
    message.UpdateSentCount(MessageId)
   End If
   sentCount = message.SentCount

   progress("PrimaryTotal") = totalRecipients.ToString
   progress("PrimaryValue") = sentCount.ToString

   percentComplete = (sentCount / totalRecipients) * 100

   progress("PrimaryPercent") = percentComplete.ToString
   progress("CurrentOperationText") = "Sending your email...please wait."

   loopCount += 1
  Loop
 Catch ex As Exception
 End Try

End Sub
  
  
The UpdateSentCount method, SentCount property are all in the business layer.  The details are not important, you just need to know that you should update them periodically to give the user information on the asychnronous process's progress.  In the case of a large email recipient list, I didn't want to be updating the value on every run through the loop, hence the loopcount MOD 10 = 0.  (I update the count every 10 times through the loop).
    

The rest is pretty easy and follows the Telerik documentation

  • Update your web.config file with the appropriate httpHandler and httpModule declarations.
  • Create the Telerik.RadUploadProgressHandler.asp in the root of your application.
  • Drop the RadProgressArea and RadProgressManager on your page.
  • Customize the template if needed.  In our case, we wanted to hide some of the default values and compact the area a bit.

 

Published Wednesday, November 15, 2006 4:00 PM by chuck.boyer

Comments

No Comments
Anonymous comments are disabled

This Blog

Syndication

Powered by Community Server, by Telligent Systems
Free ASP.NET Web Hosting by ChristianASP.NET