In Asp.net Web Form app, I have Generate Report button and a Cancel button to cancel report generation process, if it takes a long time.
When I Click Generate Report it does the heavy task, after 3 seconds I try to cancel this heavy task by clicking the Cancel button.
But the server side code for Cancel button click is called after some time delay.
I even tried window.stop()
in JavaScript
to stop page loading and hit server code fast, but still, there is a delay.
Code:
protected void btnExportExcel_Click(object sender, EventArgs e)
{
// Doing Heavy Task to Generate Report
}
protected void btnCancel_Click(object sender, EventArgs e)
{
if (Response.IsClientConnected)
{
HttpContext.Current.ApplicationInstance.CompleteRequest();
}
}
<asp:Button ID="btnCancel" runat="server" Text="Cancel Request"
OnClientClick="return StopPageLoading();" OnClick="btnCancel_Click" />
function StopPageLoading() {
try
{
window.stop();
} catch (exception)
{
document.execCommand('Stop'); // for IE and other browsers
}
}
How can I allow to start another request on click fast, while current request is in processing?
How to allow UI
to be responsive?
Update:
To reproduce the situation:
- I click Export To Excel , it takes 7 minutes to process.
- While still processing I click Cancel button , it takes another 5 minutes to cancel.
I read that Concurrent request is not possible in Asp.NET because of session state makes exclusive locks.
So How to cancel fast ?
Will making my methods async
help to overcome session state exclusive locks issue ?
As in another question from you, you can do it this way
And in your
Page.aspx
Need something like this
I hope this helps you!
The problem is in IIS (or any other Web Server) architecture. The server returns a response to a client (browser) and forget it. Your first request (
btnExcelExport_Click
) must be finished before it returns response to the browser. The click onbtnCancel
starts a new request which knows nothing about the first one.The workaround is to send a long job to another
thread
. It is possible to communicate to that thread using stateobject
sent to the new thread. Something like this.Though, you can do it or not (I am not sure), it is generally not a good idea to create a long running task within ASP.NET, especially if they are background tasks. So there are some helper libraries that are for this purpose.
Did you try using the async/await operation in the code instead of synchronous
https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/
when the report generation call is asynchronous then redirect to UI once the report generation process is kicked off. Now the cancel button can be clicked when needed.
Does this help?