Sunday, March 11, 2012

queued asynchronous calls

My partner just stumbled on an aggravating factor. If this happens on a button in a gridview for which the code removes the row from the gridview (the row containing the button), the page does not seem to refresh and the UI changes are lost. The rows stays in the UI but clicking on the button does nothing because it is no longer supposed to exist (breakpoint in code-behind is never fired).

Any suggestions on preventing clicks to be queued?

Thanks!


Did you find a solution to this?


We added this:

The real update progress:

<asp:UpdateProgressID="UpdateProgress"runat="server"DisplayAfter="500">

<ProgressTemplate>

<divid="progressPopup"class="UpdateProgress">

<asp:ImageCssClass="UpdateImage"ID="imgLoading"runat="server"ImageUrl="~/images/loading.gif"/>

<asp:LiteralID="Literal1"runat="server"meta:resourcekey="Literal1Resource1"Text="Please wait..."></asp:Literal>

</div>

</ProgressTemplate>

</asp:UpdateProgress>

One that disables all clicks:

<asp:UpdateProgressID="UpdateProgressDisableAll"runat="server"DisplayAfter="0">

<ProgressTemplate>

<divclass="DisableAllPanel">

</div>

</ProgressTemplate>

</asp:UpdateProgress>

... we're only developing for IE7 so not sure if the css is cross-browser:

.DisableAllPanel

{

opacity:0;

filter:alpha(opacity=0);

background-color:White;

position:absolute;

top:0px;

left:0px;

height:100%;

width:100%;

z-index:99999999;

}


Thanks for the quick reply!

I've tried using updateprogress to prevent this, but its still possible for persistent users to keep clicking on a button and end up posting a queued request, even if you use the updateprogress to place a panel over the button. The problem I have is that each request does an action on the server, so the queued requests have viewstate that is out of sync with the server information and exceptions get thrown.

Still trying to work out how to fix this...


Looks like I may have found the answer in the documentation (rtfm, eh!) for the framework:

I put this after the script manager tag in the body.

<scripttype="text/javascript"language="javascript">

Sys.WebForms.PageRequestManager.getInstance().add_initializeRequest(CheckStatus);

function CheckStatus(sender, args)

{

var prm = Sys.WebForms.PageRequestManager.getInstance();

if (prm.get_isInAsyncPostBack()) {

args.set_cancel(true);

}

}

</script>


Nice! I'll try it out myself. I had looked at the doc but couldn't find anything back when.. my bad.

Does it work now properly now?


It works really well. You can also use

args.get_postBackElement().id

to test which object is sending the request out. I use that to determine if its a button, in which case I cancel any pending timer-based screen refreshes using

prm.abortPostBack();

so that the user always gets a near-instant response. In addition I disable/grey out all the other buttons so that the user doesn't expect to be able to click anything else. Using

prm.add_endRequest(EndRequestHandler);

I then re-enable everything when the request returns, and you can also trap errors. It is really powerful.


Hello,

Could you please post code on how this is done? I am new in this stuff and would help looking at your code to determine what is going on and how to implement the solution you propose.

Thanks

No comments:

Post a Comment