Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / ASP.NET

Priority Based Asynchronous Post-back Scheduler

4.00/5 (2 votes)
9 Jun 2011CPOL3 min read 22.9K   219  
A component that schedules asynchronous post-back based priority

Introduction

In the article, Enable Multiple Asynchronous Postbacks at the Same Time[^], Vinay Lakhanpal[^] talked about scheduling asynchronous postbacks in a FIFO manner (First In First Out). In this article, we are going to schedule these post-backs based on given priority. So urgent postbacks would be processed first.

Background

This article is based on ideas discussed in Enable Multiple Asynchronous Postbacks at the Same Time[^] by Vinay Lakhanpal[^].

The Implementation

First, we are going to create a custom control. This would be useful for reuseability. So, we extend from class WebControl and implement the IScriptControl Interface. This interface would access an embedded script resource through its GetScriptReferences() method.

VB.NET
Protected Overridable Function GetScriptReferences() _
  As IEnumerable(Of ScriptReference) Implements IScriptControl.GetScriptReferences
    Dim reference As New ScriptReference()
    reference.Assembly = "AsyncScheduling"
    reference.Name = "AsyncScheduling.AsyncSceduler.js"

    Return New ScriptReference() {reference}
End Function

The other method provided by interface IScriptControl is GetScriptDescriptors(); which provides a means of type description to the JavaScript class. But because we don't need to define an object (a JavaScript one) or even add an HTML DOM element to the document, we don't need to provide any type descriptor. We just return an empty array.

VB.NET
Protected Overridable Function GetScriptDescriptors() _
  As IEnumerable(Of ScriptDescriptor) Implements IScriptControl.GetScriptDescriptors
    Return New ScriptDescriptor() {}
End Function

Then we define the JavaScript classes:

  • EventReference: which represents a pair of event target and event argument of the postback.
  • Node: which represents a node to be pushed into the queue.
  • ReadyQueue: which represents the queue in which the post-back event references will be arranged.
  • And lastly AsyncSceduler: which is the main component that handles the PageRequestMaanager initializeRequest and endRequest events.

AsyncSceduler

The class AsyncSceduler provides some static (shared) fields and methods that help in the scheduling process. These fields are:

  • prm of type Sys.WebForms.PageRequestManager which manages asynchronous post-backs through events
  • pendingRequest of type Ready Queue which holds the post-backs that are ready to be passed to the server
  • prioritytable of type Array which represents a hash table of controls unique ids/priority pairs
  • logmethode of type String which is the name of the JavaScript function used for logging

The methods are:

  • initialize(logmethod) that initializes the common logic of the AsyncScheduler
  • initializeRequest that is executed on initializing a request
  • endRequest that is executed on initializing a request
  • TriggerPendingPostBack that passes a request to the server

The Queue

The idea of the queue is to arrange the nodes based on their priority which is one of the type Priority values: Real Time, High, Above Normal, Normal, Below Normal, Low, so the highest priority would be served first.

The queue consists of two pointers, head and tail, pointing to an array of pointers (Nodes); one points to the first node and the other points to the last. Each node has a pointer to point to the following node and the last node points to nothing (null). A node also has an instance of class EventReference to hold the postback and a priority value.

queue

Once we push an event reference in the queue with a given priority, we first create a node with the given values, we determine the position where to place the node based on the priority, we cut the connection between the two nodes, then we set the connections to pass through our node.

Using the Code

To use the AsyncSceduler, we first need to tag to the markup file in a common place like a master page:

ASP.NET
<%@ Register Assembly="AsyncScheduling" Namespace="AsyncScheduling" TagPrefix="cc1" %>
<cc1:AsyncSceduler ID="AsyncSceduler1" runat="server"  />

Then we can call it from the content page through the GetCurrent() method, and we just set priority to the controls through SetAsyncControlPriority() method.

VB.NET
Dim AsyncSceduler1 As AsyncScheduling.AsyncSceduler = 
		AsyncScheduling.AsyncSceduler.GetCurrent(Me)
AsyncScedular1.LogMethod = "WriteLog"

AsyncSceduler1.SetAsyncControlPriority(Button1, AjaxServerControl1.Priority.High)
AsyncSceduler1.SetAsyncControlPriority(Button2, AjaxServerControl1.Priority.AboveNormal)
AsyncSceduler1.SetAsyncControlPriority(Button3, AjaxServerControl1.Priority.Normal)
AsyncSceduler1.SetAsyncControlPriority(Button4, AjaxServerControl1.Priority.Low)
AsyncSceduler1.SetAsyncControlPriority(Button5, AjaxServerControl1.Priority.BelowNormal)
AsyncSceduler1.SetAsyncControlPriority(Button6, AjaxServerControl1.Priority.RealTime)

Point of Interest

Because this component has no element associated with it, we just add a static call to initialize common logic. We use Page.ClientScript to register this code block during the Control.Render() method, just like:

VB.NET
Protected Overrides Sub Render(ByVal writer As HtmlTextWriter)
    If Not Me.DesignMode Then
        sMgr.RegisterScriptDescriptors(Me)
    End If

    Dim builder As New Text.StringBuilder(String.Format_
	("AsyncScheduling.AsyncSceduler.initialize('{0}');" & vbCrLf, Me.LogMethod))
    For Each _uniqueid As String In PriortyTable.Keys

        builder.AppendFormat("AsyncScheduling.AsyncSceduler.prioritytable['{0}'] = _
	AsyncScheduling.Priority.{1};" & vbCrLf, _uniqueid, PriortyTable(_uniqueid))
    Next

    Me.Page.ClientScript.RegisterStartupScript(GetType(AsyncSceduler), _
	"AsyncSceduler", builder.ToString, True)

    MyBase.Render(writer)
End Sub

History

  • Friday May 27, 2011: First version
  • Thursday June 9, 2011: Converted the JavaScript class to provide static members and added a section to describe that

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)