Friday 27 December 2013

Web application client side caching

This is a very important aspect to understand that how the browser caching works and when and how to control it. I will discuss a few basic things here about the client side caching.

You can enable or disable browser caching of your web pages by specifying following tag in your application's web.config file:

 <system.web>
          <caching>  
 <outputCache  enableOutputCache="false" >  
 </outputCache>
 </caching>
 </system.web>

If you want more control over caching behavior than you should specify it in the page itself. By specifying the caching inside the webpage you can control browser caching at the page level.

Add a page directive to your webpage like this:

<%@ OutputCache Duration="1" NoStore="true" VaryByParam="*" %>

All the three attributes in this directive are required. Here we can specify the duration for which the page should be cached by setting the Duration attribute. The duration is considered in milliseconds.
With attribute VaryByParam you can specify when the page should make a fresh request. If '*' is mentioned for this attribute value that means for each parameter value in the request query string the browser will make a fresh request, if the value of any parameter changes in subsequent request.
For example if i make two subsequent request as:
http://blogger.com?id=121&tag=abc
http://blogger.com?id=122&tag=abc

In both the cases above the browser will make fresh request because the parameter value for 'id' has changed.
If you want the browser to make a fresh request on the change of particular parameter then you can specify it like, VaryByParam="tag".

By setting the value of NoStore you can specify whether you want the browser cache that page or not.

Here is a very tricky point in browser caching that you must remember or it may give you great headache at times and that is, as per the w3c standards the GET requests are always cacheable whether the caching is enabled or disabled. So whenever you are making request from javascript and do not want the page to be cached, make sure that you are making POST request.



Wednesday 25 September 2013

ASP.Net WebMethod

One day I thought, how convenient it would have been if I could call a server method from my client script on my web page, simply, as I can call a javascript method from another javascript method.
And yes, there is the asp.net WebMethod attribute with which we can do a sever method calling as calling a method locally. WebMethod with JQuery and a little bit of JSON and we are done.
Here is the code snippet to implement the same:

Asp.Net Code

[WebMethod] 

public static string ServerMethod(string name)
{    
     return "Hi " + name;
}

WebMethod attribute requires reference to System.Web.Services.
And remember to mark the method static, otherwise it will not work.

Client Script

function GetResultFromServer()
{
   $.ajax({ type:"post",
   url: "Default.aspx/ServerMethod",
   data: JSON.stringify({name:"Boraska"}),
   contentType: "application/json; charset=utf-8",
   dataType: "json",
   success: function (data) {
      alert("Hurreyyy! I got " + data.d + "from server method.");
      }
  });}
This small script and WebMethod attribute do the fantastic job, no need to go in detail of page life-cycle events and many more things.
Now, here again, there are few things that needs to be taken care to make this work:
  • Url contains the method name which you want to call. Specify the url carefully. If you need you can pass query strings as well with url.
  • Data is the parameters you want to pass to the server method. The name and number of parameters must match to the server method what you are passing from here.
  • More than one parameters can be passed to the method but their types should be compatible, I mean you can pass "abc" to object type parameter but not to int type of parameter in the server method.


Tuesday 24 September 2013

Sequencing thread access with ManualResetEvent and AutoResetEvent

Threads! tiny things can make a very complex and sophisticated article like clothe and many more. But when not handled with care and knowledge, can spoil all your work and sometimes almost impossible to separate out.
Yes this is the best simulation of nature of .Net Threads. We call thread a light-weight process in terms of many aspects. And this light-weight thing can make very sophisticated software applications, but when used inappropriately can result in hell of bugs in your application. A multi-threaded application is hard to debug and understand. Yes, but most of the sophisticated applications cannot be written without threading.

In this post I am covering ManualResetEvent and AutoResetEvent.

ManualResetEvent and AutoResetEvent are basically used for sequencing the thread access in a multithreaded environment, although can also be used for implementing exclusive access to a shared resource.
Here is an example how to use AutoResetEvent for mutual exclusion

class Program
{
    static void Main(string[] args)
    {
        ThreadingTest.StartTasks();
    }



public class ThreadingTest
{
    private static AutoResetEvent are = new AutoResetEvent(false);
    public static void StartTasks()
    {
        Thread[] threads = new Thread[15];
        for (int i = 0; i < 15; i++)
        {


            threads[i] = new Thread(new ThreadStart(WriteToFile));

            threads[i].Name = i.ToString();


            threads[i].Start();
        }


        Console.WriteLine("Press enter key to start.");
        Console.ReadLine();
        are.Set(); 
        for (int i = 0; i < 15; i++)
        {


            threads[i].Join();
        }

        Console.ReadKey();
    }
    public static void WriteToFile()
    {


        are.WaitOne();

        Console.WriteLine("Thread " + Thread.CurrentThread.Name + "Entered");
        File.AppendAllText(@"d:\test.txt", "This text can be inserted at any position.");
        Thread.Sleep(1000);
        Console.WriteLine("Thread " + Thread.CurrentThread.Name + "Exited");
        are.Set();


    }
}


But there are two points to consider here.
  1. For mutual exclusion lock or monitor is the best and easy solution. If AutoResetEvent resets automatically with WaitOne call but if both the operations WaitOne and Reset does not execute atomically, your application logic could be in great jeopardy.
  2. ManualResetEvent cannot be used for mutual exclusion in this situation as it does not reset automatically.

Now consider the above example in which we are writing to a file. In the above example the text has to be written in a sequential order to the file, what is our option then to implement that? Of course, the solution is ManulaResetEvent or AutoResetEvent. Now, see the code snippet below that explains the situation:

public class ThreadingTest
{   
    static ManualResetEvent[] mre = new ManualResetEvent[3];
    public static void StartTasks()
    {        Thread[] threads = new Thread[3];
        for (int i = 0; i < 3; i++)
        {
            mre[i] =
new ManualResetEvent(false);
        }

        threads[0] =
new Thread(new ThreadStart(Task1));
        threads[1] = new Thread(new ThreadStart(Task2));
        threads[2] = new Thread(new ThreadStart(Task3));

        for (int i = 0; i < 3; i++)
        {
            threads[i].Start();
        }
        // Signal the first event
        mre[0].Set();
    }
    public static void Task1()
    {
        // Do some work here.
        mre[0].WaitOne();
        WriteToFile(
"This is the first text that should be written in the file.");
        // Signal the next event so that other thread can write to file.
        mre[1].Set();
    }

    public static void Task2()
    {
        // Do some work here.
        mre[1].WaitOne();
        WriteToFile(
"This is the second text that should be written in the file.");
        // Signal the next event so that other thread can write to file.
        mre[2].Set();
    }

   
public static void Task3()
    {
        // Do some work here.       
        WaitHandle.WaitAll(mre);
        WriteToFile("This is the last text that should be written in the file.");
    }

   
public static void WriteToFile(string text)
    {
       
File.AppendAllText(@"d:\test.txt", text + Environment.NewLine);
    }
}

If you observe in the above code the three threads are doing their respective tasks but the access to file write is sequential. And that sequence is controlled by ResetEvents. In this situation we can use either ManualResetEvent or AutoResetEvent.
However there are situations where one is preferred over the other. You can read that in my next article ManualResetEvent or AutoResetEvent?.

ManualResetEvent or AutoResetEvent?

There are many situations when you need to sequence thread access to a resource along with mutual exclusion in a multithreaded application. Or, there are situations when you need to only sequence the tasks which are performed by different threads, a simple example would be like one thread calculates a number and another thread calculates another number and a third thread performs a division of one number by another, of course you would like to get the numbers initialised first before performing the division. So in such situations you can use Manual or AutoResetEvent. For explanation and usage of ResetEvents please refer my previous article Sequencing thread access with ManualResetEvent and AutoResetEvent. In this article I will talk about when to use ManualRsetEvent and when AutoRsetEvent?
In most of the situations both can be used interchangeably. So the question is what is the difference in them? The difference can be visualised very well with the figure below:

Flap Gate

Manual Gate


AutoResetEvent can be visualised as Flap Gate where it opens for one person and closes automatically. So the next person will need to take the permission again to pass through the gate.

ManualResetEvent can be visualised as the Manual Gate where once the gate is opened any number pf people can pass through until the gate is manually closed.

Here is an implementation of the both ResetEvent types:

public class NormalEntry
{    ManualResetEvent mre = new ManualResetEvent(false);
   
public void AllowAccessTo(Person[] persons)
    {

       
Console.WriteLine("Press enter tp open entry for VIP.");
       
Console.ReadLine();
        mre.Set();
       
Console.WriteLine("VIP passed.");
        mre.Reset();
       
Console.WriteLine("Entry closed manually.");
        Thread[] tr = new Thread[4];
        for (int i = 0; i < 4; i++)
        {

           
ParameterizedThreadStart pts = new ParameterizedThreadStart(WaitForAccess);
            tr[i] = new Thread(pts);
            tr[i].Start(persons[i]);
        }

       
Console.WriteLine("Four more person are waiting to enter.");
       
Console.WriteLine("Press enter to let all the people enter.");
        OpenEntryForAll();
    }

   
private void OpenEntryForAll()
    {

       
Thread.Sleep(1000);
       
Console.WriteLine("Entry opened for all.");
        mre.Set();
    }

   
private void WaitForAccess(object obj)
    {
        mre.WaitOne();

       
Person p = (Person)obj;
       
Console.WriteLine(p.Name + " Passed.");
    }
}
public class BarredEntry
{    AutoResetEvent are = new AutoResetEvent(false);
   
public void AllowAccessTo(Person[] persons)
    {

       
Thread[] tr = new Thread[4];
       
for (int i = 0; i < 4; i++)
        {

           
ParameterizedThreadStart pts = new ParameterizedThreadStart(WaitForAccess);
            tr[i] =
new Thread(pts);
            tr[i].Start(persons[i]);
        }
        are.Set();

       
Console.WriteLine("First Person swiped the card.");
    }

   
private void WaitForAccess(object obj)
    {
        are.WaitOne();

       
Person p = (Person)obj;
       
Console.WriteLine(p.Name + " Passed.");
        are.Set();

       
Console.WriteLine("Next Person swiped the card.");
    }
}


public class Person
{
   
public string Name;
}
public class Premises
{
   
Person[] persons = new Person[4] { new Person() { Name = "p1" }, new Person() { Name = "p2" }, new Person() { Name = "p3" }, new                 Person() { Name = "p4" } };
   
public void ManageAccess()
    {

       
NormalEntry ne = new NormalEntry();
        ne.AllowAccessTo(persons);

       
BarredEntry be = new BarredEntry();be.AllowAccessTo(persons);
    }
}


class Program
{    static void Main(string[] args)
   {  
       Premises p = new Premises();
       p.ManageAccess();
   }
}


In the code above the sequence is not maintained only I have only explained the situations where AutoResetEvent fits better than ManulResetEvent.