Threading in ASP.NET
Blog Home

Recent Blog Posts
Show All Posts

Threading is a technique used to give the user the impression that multiple tasks are executing at the same time. The .NET Framework provides us with many types that allow us to easily and quickly add multi-threading to our .NET Web application. I'll assume that you have some familiarity with ASP.NET and at least some experience with writing code in Visual Basic.

Through the tutorial we'll build a pretty simple Web application that should be a good example of some basic threading concepts. Basically we'll have 2 textboxes in which to enter a phrase, and to enter a time period in which you want the phrase to be rebuilt. Our Web threading application consists of 2 pages, one of which is the page that will start the thread, while the other is a results page that shows us the progress of our thread. The code provided should be very portable and allow you to implement your own threading application very quickly.

First, we need to import the System.Threading Namespace so we can access the Thread class provided in the .NET Framework. Add this line to the top of your .aspx/.ascx file:

<%@ Import NameSpace="System.Threading" %>

or in VB.NET:

Imports System.Threading

Now for demonstration purposes, here is a sample long running method. In a real life situation this method would most likely perform a task like processing a Web form, or completing a time-consuming database query.

Public Sub SomeLongMethod()

       'your code that takes a while to execute

End Sub

Now to execute this method and not leave our Web form hanging, we'll start a new thread and let SomeLongMethod execute on this new thread. To do this, we have a few options. The technique I'll use is to set up a new method that will start our new thread running. Here's a sample thread starter function:

Public Sub SomeLongMethod_Thread()

'first, declare a new Thread, passing the constructor the address
'of SomeLongMethod. NOTE: SomeLongMethod can be replaced with your
'own method

Dim NewThread As Thread = New _
           Thread(AddressOf SomeLongMethod)

'next we set the priority of our thread to lowest, setting
'the priority to a higher level can cause unexpected results.
NewThread.Priority = ThreadPriority.Lowest

'finally we start the thread executing

End Sub

And that's it! All we have to do now is replace our call to SomeLongMethod with a call to SomeLongMethod_Thread, and the long method will execute on its own thread. Normally, we would redirect the user to the results page at the end of the SomeLongMethod_Thread method. However in this example I left that out to prevent confusion -- I'll demonstrate it in the following example, which illustrates the use of Threading in an ASP.NET Web application.

Using Threading to Rebuild a String
The first file we'll look at is default.aspx. This will be the page where we'll get 2 values from the user, and start a new thread. The second file we'll look at is the results page, where we'll poll the Session variables created in the thread, and display current thread stats to our user. I'll go through default.aspx method-by-method, and then do the same for the results.aspx page. The source code for this file is available at the end of this tutorial.

NOTE: I've assumed that your Web server has Session variables enabled. If you have Session variables Disabled, or you have cookies disabled on your browser, the results of the following example will not display correctly.

A Simple Example (default.aspx)

Let's begin by looking at the Page_Load function for default.aspx

Sub Page_Load(ByVal sender As System.Object, ByVal e  
As System.EventArgs)

SyncLock Session.SyncRoot
'here, we initialize 3 session variables to hold our results
Session("Complete") = False
Session("Status") = ""
Session("Phrase") = ""
End SyncLock
d Sub

In this method we simply initialize 3 session variables that we'll use in our next few methods. Session("Complete") will be the sentinel for our results page. When the thread is complete we will set Session("Complete") to True. The Session("Phrase") variable will be what we use to hold our partial phrase as we slowly build it. Session("Status") is just a variable to hold the start time and the end time. Now let's look at our phrase re-building method:

Sub PhraseBuilder()

       Dim str As String = ""
       Dim i As Integer = 0

       Dim startTimeTicks As Long = 0
       Dim strStartTime As String = ""

       Dim totalSleepTime As Double = 0.0

       'log our start time, in ticks, and in Long Date format
       startTimeTicks = DateTime.Now.Ticks
       strStartTime = "Thread Started: " & DateTime.Now

       ' get phrase
       str = txtPhrase.Text

       'convert users time from seconds to milliseconds
       totalSleepTime = 1000.0
       totalSleepTime = totalSleepTime * CInt(txtTotalThreadLife.Text)
       totalSleepTime = (totalSleepTime / str.Length)

       For i = 0 To str.Length - 1

       'this method will put our thread to sleep for the specified
       'number of milliseconds. without the sleep, this method would  
       'execute too fast to see the thread working.

 'we use synclock to block any other thread from accessing
 'session variables while we are changing their values.
       SyncLock Session.SyncRoot
 Session("Status") = "Thread is " & _
 Format((i / (str.Length - 1)) * 100, "#0.00") & _
       "% complete." & " - Time Elapsed: " & _
       Format((DateTime.Now.Ticks - startTimeTicks) / 10000000 _
       , "#0.00") & " sec. Target: " & txtTotalThreadLife.Text & _
       ".00 sec."

       End SyncLock

       SyncLock Session.SyncRoot
 'rebuild phrase 1 letter at a time
       Session("Phrase") &= str.Chars(i).ToString
       End SyncLock


 'our method is complete, so set the Session variables
       SyncLock Session.SyncRoot
       Session("Status") = strStartTime & _
 "<br>Thread Complete. End Time: " & DateTime.Now & "<br>"

       Session("Complete") = True
       End SyncLock

   End Sub

Ok, now let's dissect this method a little. Basically what we're doing here is forcing a method that would otherwise run quickly to run on a schedule based on user input. This is done using the Thread.Sleep(ByVal millisecond as Integer) method. This method allows us to put the thread to sleep for the specified number of milliseconds. This Sleep method can be used in any method, not just one that's executing on a new thread.

In Conclusion
Well that's all there is to it! Hopefully you have just written your first ASP.NET application using threading.

Using threading in the right places in your applications can greatly improve Web server performance, and also provide you users with a much better Web experience.


Posted by Rajiv on Monday, March 02, 2009 at 11:53-AM under .NET / SQL Server
Post Comments (0) Back to Top  

© Copyright 2009 All rights reserved, Rajiv Sharma
Home | Contact Me | Sitemap | Privacy Notice & Disclaimer
Visitor's IP Address: