Sequence Aspnet Ajax Calls
Most of you working with asp.net AJAX update panels already know that the there is limitation with respect to multiple requests at the same time. Following section taken from Dino’s blog(http://msdn.microsoft.com/en-us/magazine/cc163319.aspx#S6) on MSDN best describes the working of asp.net AJAX and the problem.
One AJAX Postback at a Time
Since partial rendering lets you add AJAX functionality to classic ASP.NET 2.0 pages without modifying the programming model, the server lifecycle of the page is fully preserved. This holds true for postback events, loading, rendering, and view state. The amount of traffic for a typical partial rendering call is smaller than that for a classic ASP.NET call, but the size of the view state is a constant and can only be reduced through page-specific programming techniques.With partial rendering, an ASP.NET page gains the continuous feel of an AJAX page, but maintains the traditional user interface. Seen from the client-side, a partial rendering page behaves as if it is part of a single, sequential UI. Only one operation can be pending at a time, even when two concurrent operations are possible from a business viewpoint.Imagine you have a page that displays any sort of information about a customer. This page contains two buttons—one for downloading order information and one for displaying customer details. From a pure business perspective, there's nothing preventing the user from clicking the two buttons in sequence to generate two successive requests, with the second request starting before the first has completed. The two requests need the same input—the customer ID—and both are read-only, meaning there is no danger of interfering with the status of the back-end database. Nevertheless, these two calls can't run concurrently in a partial-rendering page because partial rendering is based on the classic ASP.NET programming model—each request returns markup that includes an updated view state for the whole page. If you let two requests run concurrently, you put the consistency of the page's view state at risk. Two requests sent in quick sequence send the same view state to the server, but each request returns a different view state, updated for the controls involved with the processing of the request. This means the last request to return overwrites the changes made when the first request returned. Thus, partial-rendering AJAX pages still work according to the stop-and-go pattern.To avoid these types of problems, the page request manager object automatically kills any request that is pending when a new request is placed. In light of this behavior, it is extremely important that you disable the entire UI in partial rendering pages. This is to ensure that users can't interact with the whole page for the duration of the current request. As you can see, this statement directly contradicts one of the key benefits of AJAX—asynchronous interaction. So the basic problem with this is that in complex applications with multiple buttons(postback elements) in an update panel the user can always trigger two post backs. We can prevent that from the front end using some UI behaviours like hiding and showing behaviours but it is still very difficult to prevent multiple posts happening. When multiple posts happen for a mission critical application it is mandatory that we override the last win policy which AJAX.
Application
In this example I have added two buttons to the update panels and both the buttons just wait for 3 seconds before populating the corresponding label.When you click both the button in a span of 3 secs then only the latest click would work. But the following code will ensure that both the clicks work.
<script type="text/javascript">
Sys.Application.add_load(ApplicationLoadHandler)
function ApplicationLoadHandler(sender,
args) {if (!Sys.WebForms.PageRequestManager.getInstance().get_isInAsyncPostBack())
{
Sys.WebForms.PageRequestManager.getInstance().add_initializeRequest(InitializeRequest);
}
}
function InitializeRequest(sender, args) {
var prm = Sys.WebForms.PageRequestManager.getInstance();
var eventId = args._postBackElement.id;
if (prm.get_isInAsyncPostBack()) {
setTimeout("Wait('"
+ eventId + "')",
2000);args.set_cancel(true);
}
}
function Wait(eventId) {__doPostBack(eventId, '');
}
</script>
The way it works is we
need to add the InitilizeRequest handler to the Page Request Manager. In the
Initialize Request method we detect whether there is an async post back in
progress if yes then we wait for 2 sec and do the post after that.The Timer
function in asp.net AJAX also has a similar code to handle multiple timers on a
single page.Following are the code snippets from Timer class.
function Sys$UI$_Timer$_raiseTick() {
this._startTimer();
if ((this._pageRequestManager === null) || (!this._pageRequestManager.get_isInAsyncPostBack())){
this._doPostback();
this._postbackPending = false;
}
else {this._postbackPending = true;
}
}
function Sys$UI$_Timer$_handleEndRequest(sender, arg){
var dataItem = arg.get_dataItems()[this.get_id()];
if (dataItem){this._update(dataItem[0],dataItem[1]);
}
if ((this._postbackPending === true) && (this._pageRequestManager
!== null)&&(this._pageRequestManager.get_isInAsyncPostBack()
=== false)){
this._postbackPending = false;
this._doPostback();
}
}
This is not tested for all the scenarios but you can extend the idea.
You can download the code from here (http://sequenceaspnetajax.codeplex.com).