Monday, 17 July, 2017 UTC


Summary

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>
    /// Сводное описание для 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">Таймер: </label>
        <label id="lblCounter" style="display:block">Счетчик: </label>
        <input type="button" id="btnStartStop" value="Старт" 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("Стоп");
        Ask();
    }
    else $('#btnStartStop').val("Старт");

    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("Таймер: " + 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("Счетчик: " + 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.
 
The post Implementing Timer and Counter of Loaded Strings on Web Form appeared first on {coding}Sight.