If you ever try to do more than one simultaneous partial update with Asp.net Ajax Update Panel, I guess you already found that Asp.net Ajax Framework cancel the current update request and starts the new one. You think I am kidding? Okay lets try the following code:

The example is quite simple, I have two update panel which UpdateMode is set to Conditional, upon clicking the buttons inside the update panel I am doing a fake delay of 5 seconds then printing the current time of the server in the labels. Okay now run the code and click the first button and then click the second button in 5 seconds so that you can do simultaneous update. What happens, the first label never gets updated? Yes this is the nature of update panel, it cancels the current call and start executing the new one. You can get a more clear picture if you run it in FireFox with FireBug, Open FireFox Click Tools->FireBug->Open FireBug, then move to the Console tab in the firebug and repeat the button clicks, you will find only the last request spinning animation gets completed.

I can understand the Update Panel does a monsters job for us, executing the full life cycle of the page in the server, generating the updated part of the page, downloading new scripts, updating viewstates etc and that is why it needs to work serially. But how come it discards it current update request once it found a new request? is not it better if it queues the new request and execute it once the current request completes?

The only difference you will find from the previous one that I have added a new JavaScript file PageRequestManagerEx.js and called a method PageRequestManagerEx.init(). Now run this page and repeat the button clicks, you will find the complete source in the bottom of this post. If you run it in FireFox with FireBug, you will find that no matter how many clicks you made in those buttons there is only one concurrent call and once the current call completes it executes another call. Yes as you have guessed the new JavaScript file which I just added does the trick. Now let us see what is in the JavaScript file.

var PageRequestManagerEx =
{
_initialized : false,
init : function()
{
if (!PageRequestManagerEx._initialized)
{
var _callQueue = new Array();
var _executingElement = null;
var prm = Sys.WebForms.PageRequestManager.getInstance();
_prm.add_initializeRequest(initializeRequest);
_prm.add_endRequest(endRequest);
PageRequestManagerEx._initialized = true;
}
function initializeRequest(sender, args)
{
if (_prm.get_isInAsyncPostBack())
{
//if we are here that means there already a call pending.
//Get the element which cause the postback
var postBackElement = args.get_postBackElement();
//We need to check this otherwise it will abort the request which we made from the
//end request
if (_executingElement != postBackElement)
{
//Does not match which means it is another control
//which request the update, so cancel it temporary and
//add it in the call queue
args.set_cancel(true);
Array.enqueue(_callQueue, postBackElement);
}
//Reset it as we are done with our matching
_executingElement = null;
}
}
function endRequest(sender, args)
{
//Check if we have a pending call
if (_callQueue.length > 0)
{
//Get the first item from the call queue and setting it
//as current executing item
_executingElement = Array.dequeue(_callQueue);
//Now Post the from which will also fire the initializeRequest
_prm._doPostBack(_executingElement.id, '');
}
}
}
}
if (typeof(Sys) != 'undefined')
{
Sys.Application.notifyScriptLoaded();
}

The PageRequestManagerEx is a Static class which hooks the initializeRequest and endRequest events of the original PageRequestManager. Then in the initializeRequest it first checks if there is an ongoing update, if so it cancel the new request and adds the control in a queue which cause the postback. Then in the endRequest it check if there is any pending call in the queue, if so it executes it. This loops gets executed until all the call in the queue get completed.

Lets me know if you found any issue. I will be also very curious to know why update panel does not behave like this?

//We need to check this otherwise it will abort the request which we made from the //end request if (_executingElement != postBackElement) { // Grab the event argument value var evArg = $get("__EVENTARGUMENT").value;

//Does not match which means it is another control //which request the update, so cancel it temporary and //add it in the call queue args.set_cancel(true); Array.enqueue(_callQueue, new Array(postBackElement, evArg)); }

//Reset it as we are done with our matching _executingElement = null; } }

Can anybody tell if the requests can be executed simultaneously rather than queueing. I click button 1 at 12:40:20 and button 2 at 12:40:21, it should say result as 12:40:25 for the first and 12:40:26 for the second.

Really great tips, BUT,...I cant seem to get it to work with Master Page.

I tried everything... (i must miss something).I tried ScriptManagerProxy on the content page with ScriptReference set to the path of the js file.I also tried to simply put this below onto the content page, <script type="text/javascript"> PageRequestManagerEx.init(); </script>still doesnt work.Can you please point me to the right direction?email is orangejim@gmail.com.Appreciate it

//We need to check this otherwise it will abort the request which we made from the //end request if (_executingElement != postBackElement) { // Grab the event argument value var evArg = $get("__EVENTARGUMENT").value;

//Does not match which means it is another control //which request the update, so cancel it temporary and //add it in the call queue args.set_cancel(true); Array.enqueue(_callQueue, new Array(postBackElement, evArg)); }

//Reset it as we are done with our matching _executingElement = null; } }

function endRequest(sender, args) { //Check if we have a pending call if (_callQueue.length > 0) { //Get the first item from the call queue and setting it //as current executing item _executingElement = Array.dequeue(_callQueue);

Hi, great help, thanks... I'm using this piece of javascript on an intensive page, where I have some parts of the page that need to happen in the background.... their postbacks can be interrupted by other ajax controls on the page, but they need to be executed eventually... So they had to be sequentially executed, but sometimes delayed.... I made some adjustments, maybe someone else needs them too?

But I have to make a little precision : the first argument of a postback, which correspond to the __EVENTTARGET parameter, is not always the postback element id.

Just make a little website with all types of controls in an updatepanel to test it. You can use the method "Page.ClientScript.GetPostBackEventReference(Control c, string arguments)" on the server side to get the javascript instruction to make a postback from a control and compare the first parameter to the HTML elemnt attributes. It's offently the name attribute which is used but not always.

The best way to get the good parameter is to extract it from the initial postback request url parameters which are accessible like that in the initialize method :args.get_request()._body

You have to extract the values for __EVENTTARGET and __EVENTARGUMENT parameters and use those in the postback call.

I need your help! ;) I used Matthew's version and it not works fine. When there are simultaneous 2 asyncpostbacks, the second asyncpostback not pass for the server event, but yes for de "initializeRequest" and "endRequest" client functions. Why? I can't find the solution. Can anyone help me?

I tried all the solutions provided here but the error is "Sys is undefined". I have added all kinds if libraries and handlers but the problem still exists.Can some one help me out please!!!!!!!!!!!!!!!!!