Every website needs some sort of counter to keep track of users. Whenever you place a counter on your website always remember to start the count from 10,000 :) it will make a good impression. In this article we will see that how we can implement a simple counter using Asp.net and C#.


Introduction:

Every website needs some sort of counter to keep track of users. Whenever you place a counter on your website always remember to start the count from 10,000 :) it will make a good impression. In this article we will see that how we can implement a simple counter using Asp.net and C#. 

Using Application State for the Counter:

A very simple and easy way of making a hit counter is by using Application State.

protected void Session_Start(Object sender, EventArgs e)

{

Application[TOTALUSERS] = Convert.ToInt32(Application[TOTALUSERS]) + 1;

}

The problem using this approach is that if your application restarts all the count in Application variable will be lost :(.

Using Database to store the Count:

The second way to store the count in the database is by updating the previous count. This is a good idea but we have to be very careful since we don't want to access the database too often or we will be killing performance. The code below shows you a bad way of implementing counter using database.

protected void Session_Start(Object sender, EventArgs e)

{

    InsertIntoDatabase(1) // This method adds 1 to the current value in the database

}

This means that each time a new user comes to your website InsertIntoDatabase method is fired. So, if 10,000 visitors comes every day you need to update the database 10,000 times. This might work but its very very bad for performance.

Using Database with Application State:

Let's see how we can make this better by using a break point. By break point I mean a count that when reached updates the hit count in the database. This seems reasonable since than we don't have to access database each time a user visits the website. The question is that where should we store the break point? Let's say that we store this into a private const int variable. Hmm think about it this is not good, why? Well it is possible that initially your break point is 100 visitors but as your website becomes popular the break point becomes 1000. If you have stored the break point in a private cons int than in order to make your new break point active you will need to restart the application again.

The best place to store the break point is in web.config since you don't have to build your application in order to restart. In the following code I just stored my break point in web.config file.

<configuration>

<appSettings>

<add key="MAX" value="20"/>

</appSettings>

</Configuration>

Now let's see the global.asax file where we count the users.

protected void Application_Start(Object sender, EventArgs e)

{

// Retrieve the count from the database

Application[RUNNINGCOUNT] = Visit.GetTotalCount();

}

protected void Session_Start(Object sender, EventArgs e)

{

Application[TOTALUSERS] = Convert.ToInt32(Application[TOTALUSERS]) + 1;

// If you need a running count should declare another Application variable

Application[RUNNINGCOUNT] = Convert.ToInt32(Application[RUNNINGCOUNT]) + 1;

 if((int)(Application[TOTALUSERS]) >= Convert.ToInt32((ConfigurationSettings.AppSettings["MAX"])) )

 {

 Visit.Count((int) Application[TOTALUSERS]);

// // Initialize the count again

 Application[TOTALUSERS] = 0;

}

In Application_Start I am retrieving the total count from the database. This event is fired once when the application starts. Performance wise this is not good and you can use the Visit.Count method to retrieve the total count in database. This will save you one many trips to the database.

It's also not a good idea to use Application Variable since its much slower in performance. You must be wondering where is the Count method of the Visit class. Here is a method.

public static void Count(int visits)

{

string connectionString = @"workstation id=GEEK;packet size=4096;integrated security=SSPI;initial catalog=MyDatabase;persist security info=False";

SqlConnection myConnection = new SqlConnection(connectionString);

SqlCommand myCommand = new SqlCommand("UPDATE Visitor SET TotalVisits = ( @Visits + TotalVisits) WHERE VisitID = 1",myConnection);

myCommand.Parameters.Add("@Visits",SqlDbType.Int,4);

myCommand.Parameters["@Visits"].Value = visits;

myConnection.Open();

myCommand.ExecuteNonQuery();

myConnection.Close();

}

It's a good idea to use static variables instead of Application State variables. In the attached files I have included the code which uses the static variables and also the database script.

Also when moving any value inside the Application variable don't forget to use Application.Lock() and Application.UnLock(). You can also look into using C# keywords lock which does not locks the application thread.

I hope you like the article, happy coding and don't forget to download the attached files.