Introduction
. Whether we use Ajax or not, if it is a very long running process the browser may show a time-out error.
In case of ASP.NET AJAX if we use a script manager then we also have to define the time-out for the request which can be difficult in the scenario where we cannot predict how long a process will take to execute.
In this article we will discuss about this issue and how to use Ajax to handle long running process by using IAsyncResult and ICallbackEventHandler.
In case of ASP.NET AJAX if we use a script manager then we also have to define the time-out for the request which can be difficult in the scenario where we cannot predict how long a process will take to execute.
In this article we will discuss about this issue and how to use Ajax to handle long running process by using IAsyncResult and ICallbackEventHandler.
Web applications are based on a client-server architecture, so when the client hits the server the server will reply. If a long process is running on the server, then we may need some mechanism to determine when the long process is over. The long process can also delay the execution of other processes. To handle this issue we will use IAsyncResult . Using this interface and delegates we will able to run asyncronous processes on server side and invoke one method on server side while continuing with other tasks; once first method is complete it will automatically call another server method so that we can update some parameters say VAR1 and VAR2. And using ICallback we can check for VAR1 and VAR2, as soon as we get updated values, we will change status of long running method on client.
Using IAsyncResult, delegates and AsyncCallback
Classes which support asynchronous operations implement the IAsyncResult interface. IAsyncResult objects are passed back to methods invoked by AsyncCallback when an asynchronous operation completes. Classes which supports AsyncCallback in their methods return object of type IAsyncResult, for example - FileStream.BeginRead and FileStream.EndRead (these methods support AsyncCallback hence the return type isIAsyncResult). The same is true for BeginGetRequestStream method of WebRequest.
If we look at the parameters in these methods there is an AsyncCallback parameter which is the method that gets called once Async method is over. In our code this method isCallBackMethod.
If we look at the parameters in these methods there is an AsyncCallback parameter which is the method that gets called once Async method is over. In our code this method isCallBackMethod.
On server side, we have used a delegate and on the button click event the function namedDoSomething() gets called. This function take cares of the LongRunningMethod registration for the delegate and invoking of LongRunningMethod. While invoking LongRunningMethodwe register the AsyncCallback method i.e. CallBackMethod.
CallBackMethod method can also be used to do other operations which may be dependent on the LongRunningMethod.
We will create a simple LongRunningMethod as follows:
private void LongRunningMethod(string name)
{
Thread.Sleep(60000 * 5);//This will run for 5 mins
}
We will now declare a delegate for above function , parameters for the delegate and the method should be same:
private delegate void LongRun(string name);
private delegate void LongRun(string name);
Implementation of the Async process on server side:
private IAsyncResult DoSomething()
{
LongRun Long = new LongRun(LongRunningMethod);
// Delegate will call LongRunningMethod
IAsyncResult ar = Long.BeginInvoke(“CHECK”,new AsyncCallback(CallBackMethod),null); //”CHECK” will go as function parameter to LongRunningMethod
return ar;
//Once LongRunningMethod is complete CallBackMethod method will be invoked.
}
private IAsyncResult DoSomething()
{
LongRun Long = new LongRun(LongRunningMethod);
// Delegate will call LongRunningMethod
IAsyncResult ar = Long.BeginInvoke(“CHECK”,new AsyncCallback(CallBackMethod),null); //”CHECK” will go as function parameter to LongRunningMethod
return ar;
//Once LongRunningMethod is complete CallBackMethod method will be invoked.
}
private void CallBackMethod(IAsyncResult ar)
{
AsyncResult Result = (AsyncResult)ar;
LongRun Long = (LongRun)Result.AsyncDelegate;
Long.EndInvoke(Result);
}
{
AsyncResult Result = (AsyncResult)ar;
LongRun Long = (LongRun)Result.AsyncDelegate;
Long.EndInvoke(Result);
}
Long.BeginInvoke in DoSomething will invoke LongRunningMethod method. While implenting this just check the parameters for BeginInvoke in .NET.
CallBackMethod gets called automatically after LongRunningMethod. CallBackMethod is used to end the invocation of the delegate.
On button click event we will call DoSomething function:
protected void Button1_Click(object sender, EventArgs e)
{
Response.Write(“Long running process is started”);
Session["result"] = null;
IAsyncResult res = DoSomthing();
Session["result"] = res;
}
protected void Button1_Click(object sender, EventArgs e)
{
Response.Write(“Long running process is started”);
Session["result"] = null;
IAsyncResult res = DoSomthing();
Session["result"] = res;
}
Now we will implement ICallbackEventHandler for cheking status of the process. If you are not familiar with ICallBack please refer to my introductory article Using ICallbackEventHandler in ASP.NET
Add following lines of code on server side:
public string GetCallbackResult()
{
if (res.IsCompleted)//Checking whether process is complete
{
IAsyncResult res = (IAsyncResult)Session["result"];
if (res.IsCompleted)
{
return “SUCCESS”;
}
}
return “FAIL”;
}
Add following lines of code on server side:
public string GetCallbackResult()
{
if (res.IsCompleted)//Checking whether process is complete
{
IAsyncResult res = (IAsyncResult)Session["result"];
if (res.IsCompleted)
{
return “SUCCESS”;
}
}
return “FAIL”;
}
public void RaiseCallbackEvent(string args)
{
// Perform any operations here.
}
{
// Perform any operations here.
}
And on client side we will add two JavaScript function:
<form id=”form1″ runat=”server” >
<asp:Button ID=”Button1″ runat=”server” Text=”Button” OnClick=”Button1_Click” />
<div id=”Wait”>Click button to start long running process.</div>
<script language=”javascript”>
function CallServer()
{
window.document.getElementById(“Wait”).innerText = window.document.getElementById(“Wait”).innerText + “.”;
<%= ClientScript.GetCallbackEventReference(this,”", “ShowResult”, null) %>;
}
function ShowResult(eventArgument,context)
{
if(eventArgument == “SUCCESS”) {alert(‘Done’);};
else setTimeout(“CallServer()”,60000);//Priodic call to server.
}
</script>
</form>
<form id=”form1″ runat=”server” >
<asp:Button ID=”Button1″ runat=”server” Text=”Button” OnClick=”Button1_Click” />
<div id=”Wait”>Click button to start long running process.</div>
<script language=”javascript”>
function CallServer()
{
window.document.getElementById(“Wait”).innerText = window.document.getElementById(“Wait”).innerText + “.”;
<%= ClientScript.GetCallbackEventReference(this,”", “ShowResult”, null) %>;
}
function ShowResult(eventArgument,context)
{
if(eventArgument == “SUCCESS”) {alert(‘Done’);};
else setTimeout(“CallServer()”,60000);//Priodic call to server.
}
</script>
</form>
After each 60sec we are invoking a callback to server which will check whether long running process is over or not. We can decide the callback period depending upon the long running process timing.
Comments
Post a Comment