tesicg tesicg - 1 month ago 14
ASP.NET (C#) Question

Using static variables instead of Application state in ASP.NET

I plane to use static variables instead of Application state in ASP.NET and am wondering if this is correct approach:

[Global.asax.cs]

...

public class Global : System.Web.HttpApplication
{
void Application_Start(object sender, EventArgs e)
{
// Code that runs on application startup

}

...

private static Dictionary<string, object> cacheItems = new Dictionary<string, object>();
private static object locker = new object();

public static Dictionary<string, object> CacheItems
{
get
{
lock (locker)
{
return cacheItems;
}
}

set
{
lock (locker)
{
cacheItems = value;
}
}
}

public static void RemoveCacheItem(string key)
{
cacheItems.Remove(key);
}

...
}


As you can see I use automatically created Global.asax (and code behind) file. I've added some static variables and methods. I can use them after in this manner:

[some .cs file]
foreach(KeyValuePair<string, object> dictItem in Global.CacheItems)
{
...


Is this the right way or I should create new class instead of existing Global? If I should create new class how can I do that and where?

Answer

What Microsoft says

ASP.NET includes application state primarily for compatibility with classic ASP so that it is easier to migrate existing applications to ASP.NET. It is recommended that you store data in static members of the application class instead of in the Application object. This increases performance because you can access a static variable faster than you can access an item in the Application dictionary.

reference : http://support.microsoft.com/default.aspx?scid=kb;en-us;Q312607

My expirience

The main different between static variables and Application state, is that the Application state is the same across all threads and pools, but the static is the same only per pool.

After new tests I see that the Application state variables are the same as static variables, and they just reference to a static variable on the application, and they just exist for compatibility reasons as microsoft says

If you have 4 pools running your site (web garden) then you have 4 sets of different static memory.

Your code

About your code, you have bug for the way you try to access your dictionarry data, and you will going to have errors in real web. This part of the code is lock the variable of the full Dictionary but not lock the change you going to make when you use it.

 // this is not enough to manipulate your data !
 public static Dictionary<string, object> CacheItems
    {
        get{ lock (locker){return cacheItems; }   }    
        set{ lock (locker){cacheItems = value;}  }
    }

The correct approach is to lock all actions of add/remove until you done, for example.

private static Dictionary<string, object> cacheItems = new Dictionary<string, object>();
private static object locker = new object();
public Dictionary<string, object> CacheItems
    {
        get{ return cacheItems; }   
        set{ cacheItems = value;}  
    }

SomeFunction()
{
  ...
  lock(locker)
  {
    CacheItems["VariableName"] = SomeObject;
  }
  ...
}

From the other hand when you manipulate data on application state you need to use the global lock of it Application.Lock(); and Application.UnLock(); for example

Application.Lock();
Application["PageRequestCount"] = ((int)Application["PageRequestCount"])+1;
Application.UnLock();

To close with a result:

Avoid Application state and just use static variables on your code.