📜 ⬆️ ⬇️

I want a timer and a count of loaded lines on a web form

... the report was formed for a long time. The hourglass and blue stripe tended to sleep. At first, he wanted a monkey that climbs the stairs, then a thermometer, but in the end there was a timer and a counter. A silly smile and a kind, sympathetic look makes wonders.

In the process of developing forms for reporting, the user wanted to see the process of loading data from the database. He wanted the stopwatch to be turned on after pressing the button, and as the lines were received, their number was displayed on the form. It was necessary to implement this as part of an existing project on ASP.NET.

Solving this problem, I was faced with the problem of choosing the method of data exchange with the server, since it had to transfer data and get some kind of response without overloading the page. In addition to the cardinal method - to rewrite everything in MVC, there are other ways. Most of them were described in the article How to execute client-side callback to a server in ASP.NET . You can also use Callback controls from DevExpress or similar commercial products.
In the case described, I used a method that I learned while reading Dino Esposito. It's about HTTPHandler. Its advantage is a minimum of code that the server performs compared to other methods, hence the high speed, which ASP.NET applications really lack. On the client side, I used jQuery and the setTimeout function.

The server-side code looks like this:


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 test - 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 side of the client, you also need to add a couple of lines:


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> 


File askHTTPHandler.js:


 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 process, an annoying memory leak on the client side was discovered. Solved it with the code below:
 var noop = function () { }; if ($ajaxQ != null) { $ajaxQ.onreadystatechange = $ajaxQ.abort = noop; $ajaxQ = null; } 

Pre-polaziv on the Internet and stumbled on this link: Memory Growing to Heaven

Conclusion


In the process of working with ASP.NET, more and more have to mix in the direction of a thick client and use the server as a data source. HTTPHandler copes well with this task, allowing you to save ASP.NET-specific functionality and bypass its drawbacks.

PS


This solution, in addition to informing the user, also helped to catch the bugs associated with the provider to the Oracle database. From time to time, when receiving data from the server, the speed of reading lines began to fall very quickly. Fix it turned out by setting the Min Pool Size and Max Pool Size to 23.

Source: https://habr.com/ru/post/253875/


All Articles