A recurring theme when programming any UI environment is keeping the user updated about the progress of a long-running operation. If you're programming Windows Forms, you can use the BackgroundWorker component and show progress updating using the Progress
control. Programming for the Web requires a slightly different
strategy. ASP.NET AJAX support includes a component for this—the ASP.NET
AJAX UpdateProgress control.
UpdateProgress controls display during asynchronous postbacks. All UpdateProgress controls on the page become visible when any UpdatePanel control triggers an asynchronous postback.
Here's an exercise for using an UpdateProgress control on a page.
Using the UpdateProgress control
Add a new page to the AJAXORama site named UseUpdateProgressControl.aspx.
Drag a ScriptManager from the Toolbox onto the page.
Drag an UpdatePanel onto the page. Give the panel the ID UpdatePanelForProgress so that you can identify it later. Add the text This is from the update panel, and then add a Button to the update panel that will begin a long-running operation. Give it the ID ButtonLongOperation and the text Activate Long Operation.
Add a Click
event handler for the button. The easiest way to create a long-running
operation is to put the thread to sleep for a few seconds, as shown
here. By introducing a long-running operation, you have a way to test
the UpdateProgress control and see how it works when the request takes a long time to complete.
public partial class UseUpdateProgressControl : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void
ButtonLongOperation_Click(object sender,
EventArgs e)
{
// Put thread to sleep for five seconds
System.Threading.Thread.Sleep(5000);
}
}
Now add an UpdateProgress control to the page. An UpdateProgress control must be tied to a specific UpdatePanel. Set the UpdateProgress control's AssociatedUpdatePanelID property to the UpdatePanelForProgress panel you just added. Note that you can simply use the provided droplist to select this ID. Also change the DisplayAfter value to be 100 (indicating the progress indication should begin 100 milliseconds after the refresh begins).
Add a ProgressTemplate to the UpdateProgress control—this is where the content for the update display is declared. Add a Label to the ProgressTemplate so that you can see it when it appears on the page:
<asp:UpdateProgress ID="UpdateProgress1"
runat="server"
AssociatedUpdatePanelID="UpdatePanelForProgress"
DisplayAfter="100">
<ProgressTemplate>
<asp:Label ID="Label1" runat="server"
Text="What's happening? This takes a long time...">
</asp:Label>
</ProgressTemplate>
</asp:UpdateProgress>
Run the page to see what happens. When you click the button that executes the long-running operation, you should see the UpdateProgress control show its content automatically. This graphic shows the UpdateProgress control in action:
Finally, no asynchronous progress
updating UI technology is complete without a means to cancel the
long-running operation. If you wish to cancel the long-running
operation, you can do so by inserting a little of your own JavaScript
into the page. You need to do this manually because there's no support
for this using the wizards. Write a client-side script block and place
it near the top of the page—inside the <head> tag. The script
block should get the instance of the Sys.WebForms.PageRequestManager. The PageRequestManager class is available to the client as part of the script injected by the ASP.NET AJAX server-side controls. The PageRequestManager has a method named get_isInAsyncPostBack() that you can use to figure out whether the page is in the middle of an asynchronous callback (generated by the UpdatePanel). If the page is in the middle of an asynchronous callback, use the PageRequestManager's abortPostBack() method to quit the request. Add a Button to the ProgressTemplate and assign its OnClientClick property to make a call to your new abortAsyncPostback method. In addition to setting the OnClientClick property to the new abort method, insert return false; immediately after the call to the abort method, as shown in the following code. (Inserting return false; prevents the browser from issuing a postback.)
<%@ Page Language="C#"
AutoEventWireup="true"
CodeFile="UseUpdateProgressControl.aspx.cs"
Inherits="UseUpdateProgressControl" %>
<!DOCTYPE html PUBLIC
"...">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script type="text/javascript">
function abortAsyncPostback()
{
var obj =
Sys.WebForms.PageRequestManager.getInstance();
if(obj.get_isInAsyncPostBack())
{
obj.abortPostBack();
}
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
</div>
<asp:UpdateProgress ID="UpdateProgress1"
runat="server"
AssociatedUpdatePanelID="UpdatePanelForProgress"
DisplayAfter="100">
<ProgressTemplate>
<asp:Label ID="Label1" runat="server"
Text="What's happening? This takes a long time...">
</asp:Label>
<asp:Button ID="Cancel" runat="server"
OnClientClick="abortAsyncPostback(); return false;"
Text="Cancel" />
</ProgressTemplate>
</asp:UpdateProgress>
<asp:UpdatePanel ID="UpdatePanelForProgress" runat="server">
<ContentTemplate>
This is from the update panel
<asp:Button ID="ButtonLongOperation"
runat="server"
onclick="ButtonLongOperation_Click"
Text="Activate Long Operation" />
</ContentTemplate>
</asp:UpdatePanel>
</form>
</body>
</html>
Warning:
Caveat Cancel: As you can see, canceling an asynchronous postback is completely a client-side affair. Canceling
a long-running operation on the client end is tantamount to
disconnecting the client from the server. Once the client is
disconnected from the server, the client will never see the response
from the server.
Also, although the client is happy that it could cancel the operation, the server might never know
that the client canceled. So, the big caveat here is to plan for such a
cancelation by making sure you program long-running blocking operations
carefully so that they don't spin out of control. Although Microsoft
Internet Information Services (IIS) 6 and IIS 7 should eventually
refresh the application pool for such runaway
threads, it's better to depend on your own good programming practices
to make sure long-running operations end reasonably nicely.
ASP.NET AJAX support provides a
great infrastructure for managing partial-page updates and for setting
up other events such as regular timer ticks. The next section looks at
the ASP.NET AJAX extender controls.