Written by 12:00 Computer Environment, Languages & Coding

Implementing Timer and Counter of Loaded Strings on Web Form

During the development of reporting forms, a user wanted to see the process of data loading from the database. He wanted the timer to start running after hitting the button, and as strings were received, their number was displayed on the form. I needed to implement this within an existing ASP.NET project.

When I was solving this task, I needed to select a system for data transfer with the server. It must receive data and a certain response without the page reload. Besides the dramatic rewrite of everything on MVC, there are other methods. For instance, we can use the callback controls from DevExpress or similar commercial solutions. In this particular case, I chose HTTPHandler. Its benefit is a minimum of code that is executed by the server in comparison with other methods. Thus, the performance of the method is quite high, unlike ASP.NET applications. On the client side, I used JQuery and the setTimeout function.

On the server side, the code looks as follows:

The TestForm.aspx.cs file
using System;

namespace HTTPHandler_Test
{
    public partial class TestForm : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }
    }
}
HTTPHandler for the text — HTTPHandlerTest.ashx.cs :
using System.Web;
using System.Web.SessionState;

namespace HTTPHandler_Test.HTTPHandler
{
    /// <summary>
    /// Summary description for HTTPHandlerTest
    /// </summary>
    public class HTTPHandlerTest : IHttpHandler, IRequiresSessionState
    {
        public void ProcessRequest(HttpContext context)
        {
            var counter = context.Request.QueryString["counter"];
            int iCount;
            if (int.TryParse(counter, out iCount))
            {
                counter = (++iCount).ToString();
            }
            context.Response.Write(counter);
        }
        

        public bool IsReusable
        {
            get
            {
                return true;
            }
        }
    }
}

On the client side, we need to add a couple of strings:

The TestForm.aspx file

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="TestForm.aspx.cs" Inherits="HTTPHandler_Test.TestForm" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
    <script src="Script/jquery-1.10.2.min.js"></script>
    <script src="Script/askHTTPHandler.js"></script>
    
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <label id="lblStatus" style="display:block">Timer: </label>
        <label id="lblCounter" style="display:block">Counter: </label>
        <input type="button" id="btnStartStop" value="Start" onclick="AskHttpHandler()"/>
    </div>
    </form>
</body>
</html>

The skHTTPHandler.js file:

var start = false;

function AskHttpHandler() {
    var dateStart = new Date();
    var counter = 0;
    start = !start;
    if (start) {
        $('#btnStartStop').val("Stop");
        Ask();
    }
    else $('#btnStartStop').val("Start");

    function Ask() {
        var difInSeconds = Math.floor(((new Date()).getTime() - dateStart.getTime()) / 1000);
        var hours = Math.floor(difInSeconds / 3600);
        var minutes = Math.floor((difInSeconds - (hours * 3600)) / 60);
        var seconds = difInSeconds - (hours * 3600) - (minutes * 60);
        if (hours < 10) hours = "0" + hours;
        if (minutes < 10) minutes = "0" + minutes;
        if (seconds < 10) seconds = "0" + seconds;
        $('#lblStatus').text("Timer: " + hours + ":" + minutes + ":" + seconds);

        var $ajaxQ = $.ajax({
            type: "GET",
            async: false,
            url: "/HTTPHandler/HTTPHandlerTest.ashx",
            data: "counter=" + counter,
            success: onSuccessAsk,
            error: onErrorAsk
        });

        var noop = function () { };
        if ($ajaxQ != null) {
            $ajaxQ.onreadystatechange = $ajaxQ.abort = noop;
            $ajaxQ = null;
        }

        function onSuccessAsk(result) {
            counter = parseInt(result);
            $('#lblCounter').text("Counter: " + result);
            if (start) setTimeout(Ask, 1000);
        }

        function onErrorAsk(result) {
            alert("error " + result.responseText);
        }
    };
}

During the development, a memory leak on the client side revealed itself. I solved it with the following code:

var noop = function () { };
        if ($ajaxQ != null) {
            $ajaxQ.onreadystatechange = $ajaxQ.abort = noop;
            $ajaxQ = null;
        }

I found this solution in the post: Memory Growing to Heaven.

Conclusion

During the work with ASP.NET, we had to shift toward the thick client and use the server as a data source. HTTPHandler does a great job and allows storing ASP.NET-specific functionality and bypass its cons.

P.S.

This solution also helped me to track bugs related to the DB Oracle provider. From time to time, when I’m getting data from a server, the speed of string read began to drop quickly. I managed to fix it with assigning value 23 to Min Pool Size and Max Pool Size.

 

Tags: , Last modified: September 23, 2021
Close