This is a migrated thread and some comments may be shown as answers.

Cancel Ajax Request

8 Answers 466 Views
Ajax
This is a migrated thread and some comments may be shown as answers.
Joel Hays
Top achievements
Rank 1
Joel Hays asked on 25 Jun 2008, 09:54 PM
I'm performing a request that can potentially take a couple of minutes to complete and I have a "Cancel" button available to the user if he doesnt want to wait.

I found a potential solution, but it doesn't work with the "Prometheus" controls : http://www.telerik.com/community/forums/thread/b311D-ttkba.aspx

The arguments for OnRequestStart don't have the XMLHttpRequest object for me to abort. Since this argument doesnt exist, is there another way I can cancel the ajax request while it's processing?

Here's what I tried to do:

I have my OnRequestStart function, assigned to my AjaxManager and i'm setting some variables outside the function to use in my Cancel button's click event. Cancel button is part of the Loading Panel, so only shows up when the request is sent.

var requestInProgress = null;
var currentLoadingPanel = "<%=LoadingPanel1.ClientID %>";
var currentUpdatedControl = "<%=UpdatedASPPanel.ClientID %>"

function OnRequestStart(sender, args)
{
    requestInProgress = args.XMLHttpRequest;
}
function CancelClick()
{
    requestInProgress.abort();
    currentLoadingPanel.Hide(currentUpdatedControl);
}

8 Answers, 1 is accepted

Sort by
0
Maria Ilieva
Telerik team
answered on 27 Jun 2008, 02:50 PM
Hi Joel Hays,

You could review the following help topic, which elaborates on this matter. Check the provided approach and verify if this works for you.

All the best,
Maria Ilieva
the Telerik team

Instantly find answers to your questions at the new Telerik Support Center
0
Joel Hays
Top achievements
Rank 1
answered on 11 Jul 2008, 10:20 PM
I found that article when I was searching for solutions, but unfortunately it doesn't work.

Once I leave the OnRequestStart function, I have no way to cancel the request. I tried putting a loop inside that function to test a value and exit either when the request completed or the request was canceled, but it appears that the Ajax request is not even initiated until that function ends, so that didn't work. That method requires returning false before the request is even started. My problem is that I have an Ajax request that's already processing on the server, and I'd like to cancel it at that time.

The other solution I tried was creating a separate worker thread from the server after the ajax request was initiated, and then looping on the server, checking whether the worker thread completed, or whether it was canceled and then either aborting the thread if the request was canceled by the user or just exit when the thread finished processing and continue to prerender.

This too failed to work. Setting the state manually to "canceled" produces the desired effects, as does setting it to "process" (these are just terms I'm jusing to indicate whether to continue processing the worker thread or abort it). However, the problem I ran into was that if I changed the value of a hidden variable on the page to the "canceled" state, the server cannot see the new value, so just continues to loop until the worker thread finishes. Because javascript didn't work, I tried creating a button that causes another ajax request to the server, however this second request does not fire until the first Ajax request completes, and so I ran into the same problem again.

I have another idea that I'd like to try which is this: create a worker thread to do my database processing, but instead of looping until this thread is complete, let the current ajax request finish and add a callback function to the worker thread. The callback function would then refresh the page with the new information retrieved from the database. This would allow a second ajax request to take place while the worker thread is running and I would be able to abort the thread through that request and refresh the page. I believe this would work, but the problem I foresee is that the Ajax Loading Panel will cease to be visible as soon as the first Ajax Request is completed. I think that I can just show and hide the Ajax Loading Panel manually from my code to get around that though.

If there is another solution that I'm missing, please let me know. I seem to be on the right track, but I'm having trouble getting all of the pieces in place.

Thanks
0
Mishel
Top achievements
Rank 1
answered on 14 Jul 2008, 01:37 PM
Hi Joel,

You can obtain a reference to the XMLHTTPObject associated with the ajax request in the OnRequestStart event. It is in the arguments parameter. Please check this forum post:
http://www.telerik.com/community/forums/thread/b311D-ttkba.aspx

Using the reference obtained in the OnRequestStart event you can later on abort the request if needed.

Also the last idea you suggested seems to be ok and you could just explicitly show and hide the LoadingPanel like this: http://www.telerik.com/help/aspnet-ajax/ajxshowhideloadingpanel.html
0
Joel Hays
Top achievements
Rank 1
answered on 14 Jul 2008, 04:54 PM

Hi Mishel,

I found that article, already, but unfortunately it doesn't work with the Prometheus controls. The XMLHttpRequest object doesn't exist in the arguments. Or at least I couldn't find it. It's not named the same if it is there, and none of the documentation for these controls has that argument listed. If it does exist under a different name for the Prometheus controls, that would be wonderful, because that's incredibly easy to use, and I don't have to jump through these hoops.

If there a way to get the XMLHttpRequest object with the Prometheus controls, please let me know.

Thanks,
Joel

0
Maria Ilieva
Telerik team
answered on 15 Jul 2008, 11:13 AM
Hello Joel Hays,

You are correct that the XMLHttpRequest object doesn't exist in the arguments for the new RadAjax for ASP.NET AJAX. Unfortunately this fact leads to limitation regrading the scenario you need to acheive. Currently the only possible workaround is presented in this online example.
Also please note that the new RadAjax is built on top of Microsoft ASP.NET AJAX, using its programming model. So, if appropriate method for canceling the Ajax request for the asp UpdatePanel exists, it will be applicable for the RadAjax controls too.

Thank you for your cooperation.

Regards,
Maria Ilieva
the Telerik team

Instantly find answers to your questions at the new Telerik Support Center
0
Joel Hays
Top achievements
Rank 1
answered on 16 Jul 2008, 07:27 PM

Hi!

Okay, so I took your suggestion and attempted to find information regarding UpdatePanels and I found the following:

Sys.WebForms.PageRequestManager.getInstance().abortPostBack();


I put this into my Cancel button onClick event and it works fine for the most part since this object uses the XMLHttpRequest object to perform async postbacks. The ajax loading panel disappears, the old data reappears, and the page is never refreshed. A limitation of this, however, is that it's purely a client disconnect. The server doesn't stop processing the request.

This would be fine, except that the server still sees the client connected (Response.IsClientConnected = True). Also, it appears that even though I've aborted the postback, another request cannot be performed because the Telerik controls are maintaining the connection, despite the posback being aborted. I could be wrong about that, but that's what seems to be happening. Any new requests must wait for the old request to be completed before they are executed.

Now my question: Is there a way to set my Ajax manager to a state that allows me to initiate another request (i.e. terminate the connection with the server)? If there is, I can check whether the client is connected in my server code and terminate the request at that point while also allowing me to perform a new request without waiting for that other request to finish.

0
Maria Ilieva
Telerik team
answered on 17 Jul 2008, 01:23 PM
Hi Joel Hays,

There is no limitation to initiate another request during the current one, for example by using control added in the AjaxManager settings to initiate the update. This will terminate the current session.

All the best,
Maria Ilieva
the Telerik team

Instantly find answers to your questions at the new Telerik Support Center
0
Ankit
Top achievements
Rank 1
answered on 08 Aug 2008, 10:10 AM
Hi,

The approach you took was right. Just a small suggestion.

Instead of having a call like ajaxmanager.ajaxRequest(args) create a generic function and make all ajax request through this function Example:-

//Make all ajax request through this function
function MakeAjaxRequest(ajaxInitiator,arguments)
{
    CancelOngoingRequest();  
    ajaxInitiator.ajaxRequest(arguments);
}

//Ajax request canceller
function CancelOngoingRequest()
{    
  var pageRequestManager= Sys.WebForms.PageRequestManager.getInstance();

  if(pageRequestManager != null && pageRequestManager != null && pageRequestManager.get_isInAsyncPostBack())
  {   
    pageRequestManager.abortPostBack(); 
  } 
}

You will also need to set RequestQueueSize to an appropriate value( based on hit and try).

Hope it helps.
Tags
Ajax
Asked by
Joel Hays
Top achievements
Rank 1
Answers by
Maria Ilieva
Telerik team
Joel Hays
Top achievements
Rank 1
Mishel
Top achievements
Rank 1
Ankit
Top achievements
Rank 1
Share this question
or