Channels ▼
RSS

.NET

Monitoring Remote Tasks in AJAX



When users start a potentially lengthy operation, the user interface should be updated to reflect that work is in progress and that results may not be available for a while. Implementing this pattern is relatively easy in Windows applications, but not in Web applications.

In Web applications, displaying a static text such as "Please, wait" just before the operation begins is easy, but what if you want to display the percentage of work done?

In Web applications, lengthy tasks occur on the server. No server environment provides facilities to push state information to the client browser. At the same time, there's no easy way either for a client to grab status information and update a progress bar.

As a result, it is up to the developer devising and implementing a solution. The Progress Indicator pattern offers guidance on how to structure the JavaScript client and the server application so that they can share information about server progress and report that information timely to the user.

The idea behind the pattern is that you design the lengthy task to expose some information about its progress. In other words, the code that implements the task doesn't include only functional steps. Instead, functional steps are intertwined with calls to an API that exposes progress information. The pattern also suggests you employ a second component that from the client monitors any exposed information by essentially polling the server.

The progress API is made of two distinct set of functions -- one for the client and one for the server. The server API offers a class through which the task can save its progress. The class gets status information and saved it somewhere -- be it a database table, a disk file, or perhaps an in-memory buffer such as the ASP.NET Cache. The server API also must expose an HTTP endpoint for the client monitor to poll to know about the status of the ongoing task.

In ASP.NET, the task can take the following form:


void ExecuteTask(int taskID, /* params */ ...)
{
    ProgressMonitor progMonitor = new ProgressMonitor(); 
    progMonitor.SetStatus(taskID, "5%");
    DoFirstStep(...);
    :
    progMonitor.SetStatus(taskID, "100%");
    DoFinalStep(...);
}

The ProgressMonitor class writes to a known location any information it receives from the task. On the server, you also need a service that can be called from JavaScript. The purpose of this service is reading the status of the task and return that to the client for UI updates. The simplest way to do this is creating a Web service that uses the ProgressMonitor class to read what a given task has saved.

For the whole machinery to work, the task must be uniquely identified with an ID. The ID must be passed to the task when it is first started. Hence, the task ID must be generated on the client. The JavaScript's Math.random function is the tool to use.

Right after starting the remote task, the client activates a monitoring channel which makes periodical calls to previously created Web service. In this way, the user interface knows in real time what's going on in the server. A piece of user interface is then updated to reflect the information imported from the server. The layout of this piece of user interface can be defined at will. It can be a progress bar (that is a HTML table) or a plain label. It is up to you how you represent the information; the trickiest part is bringing that the right server information down to the client.


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 

Video