Friday, 25 April 2014

Lazy loading in C#


If you are using Microsoft .NET 4.0 or higher, it comes with an excellent feature called Lazy Initialization. .NET 4.0 introduces a “Lazy<T>” class to support the lazy initialization, where “T” specifies the type of object that is being initialized lazily. This is a new feature of C# 4.0 and can be used when we are working with large objects.

To learn more about it, let’s create a Console application first and then create a class named “Person”. Now create a custom constructor that takes a parameter “id” as integer. In the constructor implementation, write a line to the console as “Constructor of Person <ID> has been called”. Here is the code for your reference:
Code:

public class Person
{
    public Person(int id)
    {
        Console.WriteLine("Constructor of Person " + id + " has been called");
    }
}

Now, as per default implementation, it will print the line every time when you create an instance of the class. Right? Don’t go with my words. Let’s see that in action. Let us create an array of six Person and then get the instance of the 3rd person from that collection. Need the code? Here it is for you:
Code:

class Program
{
    static void Main(string[] args)
    {
        var persons = new[]
        {
            new Person(1),
            new Person(2),
            new Person(3),
            new Person(4),
            new Person(5),
            new Person(6),
        };
 
        var person = persons[2]; // this will return the instance of Person 3
        Console.ReadLine();  // just to make sure that the application halts here
    }
}
 
As per the default behaviour, it will print six lines in the console screen. Each line represents creation of a single instance. You can check the ID to cross check it. The output will look similar to this as per our code:

Output:
 Constructor of Person 1 has been called
 Constructor of Person 2 has been called
 Constructor of Person 3 has been called
 Constructor of Person 4 has been called
 Constructor of Person 5 has been called
 Constructor of Person 6 has been called

So, think about the thousands of records! This will create instances of those many records in the memory unnecessarily without any need. User might not go to the end of the collection but the instances of the object is ready. Maximum time this creates issues in WPF, Silverlight DataGrid or List.

Now, let us modify our existing code and build the lazy initialization to it. Now instead of a Person array, we will create an array of type Lazy<Person>, that’s all! The implementation step is as shown below:
Code: 

class Program
{
    static void Main(string[] args)
    {
        var persons = new[]
        {
            new Lazy<Person>(() => new Person(1)), //Lasy<T> is important
            new Lazy<Person>(() => new Person(2)),
            new Lazy<Person>(() => new Person(3)),
            new Lazy<Person>(() => new Person(4)),
            new Lazy<Person>(() => new Person(5)),
            new Lazy<Person>(() => new Person(6)),
        };
 
        var person = persons[2].Value; // this will return the instance of Person 3
        Console.ReadLine();  // just to make sure that the application halts here
    }
}
 
If you need to fetch the 3rd person only, get it from “Value” property of the item from the array collection. So, to get the instance of person with ID=3, call person[2].Value, this will return the instance of Person 3.

Let’s run the code this time. Voila! It just called only the constructor of Person 3 this time. That means, it created the instance of person 3 when we actually used it. The other instances in the array have not been created yet. So, if we call any other instance, at that time only it will create that particular instance. Check out the below screenshot:

Output:
 Constructor of Person 3 has been called

It will not it save lot’s of processing and memory when your application runs. This feature is called as “Lazy Initialization” or “Lazy Loading”. 

Deleting cookies in IE9

Pressing Ctrl+Shift+Del brings up the delete dialog in almost all browsers (I've tested IE, Firefox, and Chrome), where you can delete cookies, form data, passwords, etc.
 

Firefox, and Chrome are working just fine. However, IE just like always acts differently. It shows the message that everything is deleted, but it actually preserves many things.
 
To test it, I simply logged into a Zerk website. We have used session cookies on our website. After clearing all the cookies by pressing Ctrl+Shift+Del and I'm still logged in IE 9 browser. Guess what? In Chrome and Firefox I get redirected to login page when performing anything after cookies got deleted.
 

Solution:
There are two types of cookies: session and persistent. In our case, session cookies should be considered.
 


In IE 9 when you use Ctrl+Shift+Del option, you delete only persistent cookies. If you want to delete session one, you must hit F12 to open the Developer Tools, click Cache and Delete session cookie.

compilation debug=”true” in ASP.Net on Production server.

Compilation debug mode “true” in web.config should be avoided when deploying an ASP.NET application on Production environment.
Disadvantages of keeping it "true" on production environment. 
  • The compilation of ASP.NET pages takes longer.
  • Code can execute slower.
  • Much more memory is used within the application at runtime.
  • Scripts and images downloaded from the WebResources.axd handler are not cached.
This last point is particularly important, since it means that all client-javascript libraries and static images that are deployed via WebResources.axd will be continually downloaded by clients on each page view request and not cached locally within the browser.  This can slow down the user experience quite a bit

When <compilation debug=”false”/> is set, the WebResource.axd handler will automatically set a long cache policy on resources retrieved via it – so that the resource is only downloaded once to the client and cached there forever!

To use sticky sessions with the load balancer or not?

In sticky Sessions, all your requests are directed to the same physical web server while in case of non-sticky load balancer May choose any web server to serve your requests.

Let's forget the sticky session for a bit and discuss the flow of how the non-sticky session works.

If your website is served by multiple web servers who sit behind a load balancer, the load balancer decides which Actual web-server each request should go to. For example, if there are 2 web servers, web 1 and web 2 behind the Load balancer, it is possible that http://www.mywebsite.com/default.aspx is served from web 1 and http://www.mywebsite.com/login.aspis served from web 2.

Now, if the requests are being served from two different servers, each server has created a session object for you and because these session objects sit on two independent boxes, there's no direct way of one knowing what is there in the session object of the other. In order to synchronize between these server sessions, you may have to use database to maintain the session information. Which is not a good idea and Now, comes the role of sticky-session.

If the load balancer is instructed to use sticky sessions, all of your interactions will occur with the same physical server, even though other servers are present. Thus, your session object will be the same throughout your entire interaction with this website.

Damn it! Is it an alternative of database session management when the website is in load balancing? Well, I'm not able to figure it out. But I would say not to use sticky session.

The problem with sticky sessions is that they limit your application scalability because the load balancer is unable to truly balance the load each time it receives requests from a client. With sticky sessions, the load balancer is forced to send all the requests to their original server where the session state was created even though that server might be heavily loaded and there might be another less-loaded server available to take on this request. This is really bad when your website is being used by millions of users a day.

I'm still trying to figure out either this new feature is a breakthrough for the load balancing or just an alternative we can use with In-proc session state in a large-scale application. I may write a next blog if I can conclude the sticky session.


I have used the New Elastic Load Balancing Sticky Sessions feature of AWS, which is explained in below the link:

Wednesday, 4 December 2013

Identity column value suddenly jumps in SQL Server 2012

While working on the Clearshift project We have faced one issue regarding the Identity column value suddenly jumps. Say 118 to 1001 or any random values. We were pulling our heads about how this is happening? It looked interesting to dig it and we found the solution.

Microsoft has changed the way they deal with identical values in SQL Server 2012 and as a result of this you can see identity gaps between your records after rebooting your SQL server instance or your server machine. There might be some other reasons for this id gaps, it may be due to automatic server restart after installing an update.

The same bug is reported to Microsoft:
Failover or Restart Results in Reseed of Identity (SQL Server 2012 - Enterprise Edition - BugID: 739013)
https://connect.microsoft.com/SQLServer/feedback/details/739013/failover-or-restart-results-in-reseed-of-identity

To avoid generating random identity values Microsoft added sequences in SQL Server 2012, we can change the way identity keys are generated! Otherwise, Identity jump is perfectly normal in SQL Server 2012.

Friday, 18 October 2013

Async file upload with jquery and ASP.NET

1. Default.aspx

<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
    CodeBehind="Default.aspx.cs" Inherits="JuqeryFileUpload._Default" %>

<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
    <script src="Scripts/ajaxfileupload.js" type="text/javascript"></script>
    <script src="Scripts/jquery.js" type="text/javascript"></script>
    <script type="text/javascript">
        function ajaxFileUpload() {
            alert("I'm in.");
            $("#loading")
               .ajaxStart(function () {
                   $(this).show();
               })
               .ajaxComplete(function () {
                   $(this).hide();
               });

            $.ajax
               (
                   {
                       type: 'POST',
                       url: 'JuqeryFileUploadHandler.ashx',
                       contentType: "application/json; charset=utf-8",
                       secureuri: false,
                       fileElementId: 'fileToUpload',
                       dataType: 'json',
                       data: { name: 'logan', id: 'id' },
                       success: function (data, status) {
                           if (typeof (data.error) != 'undefined') {
                               if (data.error != '') {
                                   alert(data.error);
                               } else {
                                   alert(data.msg);
                               }
                           }
                       },
                       error: function (data, status, e) {
                           alert(e);
                       }
                   }
               )
            return false;
        }
    </script>
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
    <p>
        Upload your file Asynchronously</p>
    <div>
        <input id="fileToUpload" type="file" name="fileToUpload" class="input" />
        <button id="buttonUpload" onclick="return ajaxFileUpload();">
            Upload</button>
        <img id="loading" src="Images/loading.gif" style="display: none;" />
    </div>
</asp:Content>



2. JQueryFileUploadHandler.ashx.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;

namespace JuqeryFileUpload
{
    /// <summary>
    /// Summary description for JuqeryFileUploadHandler
    /// </summary>
    public class JuqeryFileUploadHandler : IHttpHandler
    {
        public void ProcessRequest(HttpContext context)
        {
            if (context.Request.Files.Count > 0)
            {
                string path = context.Server.MapPath("~/Temp");
                if (!Directory.Exists(path))
                    Directory.CreateDirectory(path);

                var file = context.Request.Files[0];

                string fileName;

                if (HttpContext.Current.Request.Browser.Browser.ToUpper() == "IE")
                {
                    string[] files = file.FileName.Split(new char[] { '\\' });
                    fileName = files[files.Length - 1];
                }
                else
                {
                    fileName = file.FileName;
                }
                string strFileName = fileName;
                fileName = Path.Combine(path, fileName);
                file.SaveAs(fileName);


                string msg = "{";
                msg += string.Format("error:'{0}',\n", string.Empty);
                msg += string.Format("msg:'{0}'\n", strFileName);
                msg += "}";
                context.Response.Write(msg);
            }
        }

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

3. jQuery references and Form tag in Site.Master page.

<script src="Scripts/ajaxfileupload.js" type="text/javascript"></script>
<script src="Scripts/jquery.js" type="text/javascript"></script>
<form id="Form1" method="post" runat="server" enctype="multipart/form-data">

Tuesday, 28 May 2013

ASP.Net: Move List items from one ListBox to another ListBox using Jquery

ASP.net code behind using Update panel or XMLHttpRequest is more sower than the jquery. jquery can do this real quick and with good user experience.

$(document).ready(function() {

    $('#btnRight').click(function(e) {
        var selectedOpts = $('#lstBox1 option:selected');

        if (selectedOpts.length == 0) {
            alert("Please select item (s) to move.");
            e.preventDefault();
        } 

        $('#lstBox2').append($(selectedOpts).clone());
        $(selectedOpts).remove();
        e.preventDefault();

    });

   $('#btnLeft').click(function(e) {
        var selectedOpts = $('#lstBox2 option:selected');

        if (selectedOpts.length == 0) {
            alert("Please select item (s) to move.");
            e.preventDefault();
        }

        $('#lstBox1').append($(selectedOpts).clone());
        $(selectedOpts).remove();
        e.preventDefault();
    });
});​