What is multi-threading?
Multithreading means that a computer can work on different parts of the same program at the same time. This usually allows the program to run faster.
How to do it in asp.net?
Sometimes you need to perform long process in background in asp.net, but you need to display process progression to the user. In this post I will show you how to do it using web services and AJAX.
To start, I will show you the result:
To be simple I will use a simple formula (a+b)*d/c = result and to make the task longer I will use the Thread.Sleep method.
First I create a simple web service which perform the calculation:
namespace ASPNETMultiThreading
{
/// <summary>
/// Summary description for CalculationService
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
[System.Web.Script.Services.ScriptService]
public class CalculationService : System.Web.Services.WebService
{
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Xml,
XmlSerializeString = true)]
public string Add(double a, double b)
{
Thread.Sleep(3000);
return (a + b).ToString();
}
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Xml,
XmlSerializeString = true)]
public string Multiply(double a, double b)
{
Thread.Sleep(3000);
return (a * b).ToString();
}
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Xml,
XmlSerializeString = true)]
public string Divide(double a, double b)
{
Thread.Sleep(3000);
return (a / b).ToString();
}
}
}
After I just chain the web service call and display information to the end user via javascript:
// THREAD CALCULATION
function runCalculation() {
$get('<%= btnRunCalculation.ClientID %>').disabled = true;
$get('<%= lblCalculationInfo.ClientID %>').innerText = "Process Adding...";
checkRunButton();
var a = $get('<%= txtA.ClientID %>').value;
var b = $get('<%= txtB.ClientID %>').value;
ASPNETMultiThreading.CalculationService.Add(a, b, calculationSucceededCallback, calculationFailedCallback, "Add");
return false;
}
function calculationSucceededCallback(result, userContext) {
if (userContext == "Add") {
$get('<%= lblCalculationInfo.ClientID %>').innerText = result.text + ", Process Multiplication...";
var a = result.text;
var b = $get('<%= txtC.ClientID %>').value;
ASPNETMultiThreading.CalculationService.Multiply(a, b, calculationSucceededCallback, calculationFailedCallback, "Multiply");
}
else if (userContext == "Multiply") {
$get('<%= lblCalculationInfo.ClientID %>').innerText = result.text + ", Process Division...";
var a = result.text;
var b = $get('<%= txtD.ClientID %>').value;
ASPNETMultiThreading.CalculationService.Divide(a, b, calculationSucceededCallback, calculationFailedCallback, "Divide");
}
else if (userContext == "Divide") {
$get('<%= lblCalculationInfo.ClientID %>').innerText = result.text;
$get('<%= btnRunCalculation.ClientID %>').disabled = false;
checkRunButton();
}
}
function calculationFailedCallback(error) {
// Display the error.
alert("Service Error: " + error.get_message());
}
The advantages of this technique are that you can continue to work when you are doing you are processing, and you can display some information about the process to the user. In the demo I integrate a JQuery progress bar to visualize the task progression.
Source Code