Using static variables instead of Application state in ASP.NET

13,522

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 experience

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 dictionary 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 some conclusion:

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

Share:
13,522

Related videos on Youtube

tesicg
Author by

tesicg

Updated on October 10, 2022

Comments

  • tesicg
    tesicg about 1 year

    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?

  • tesicg
    tesicg over 11 years
    Thank you for your answer. But, I need some clarification if it's possible. Do you mean I should keep locking whole dictionary as I did, but should additionally lock particular items in Add/Remove operations as well?
  • Aristos
    Aristos over 11 years
    @tesicg to clarify, you must do ONE lock only when you change/edit/delete/find your Dictionary. So the lock you have as it is must be removed - is actually only check the Dictionary memory, is not enough.
  • tesicg
    tesicg over 11 years
    Excuse me. And one more question, which is, actually, the original question - can I just put all my new static staff in existing Global.asax.cs file as I did? Or to create new class? If I want to create new class, where should it be?
  • Aristos
    Aristos over 11 years
    @tesicg The static data is accessible by anywhere in the program. For you if you like to use it on Global.asax the most easy place to write them is there, in global.asax. If you create new class, the class are ether located inside dll that you include to your program, ether are placed in the app_code. If you have data and you like to used on pages also, is better to make a class, so you can include the reference in the pages and at the same time on global.asax and use it anywhere.
  • xr280xr
    xr280xr over 8 years
    "store data in static members of the application class", what is the application class?
  • Aristos
    Aristos over 8 years
    @xr280xr Please look at : msdn.microsoft.com/en-us/library/ms525360(v=vs.90).aspx and keep in mind that this words are from msdn support2.microsoft.com/default.aspx?scid=kb;en-us;Q312607
  • Jonathan
    Jonathan over 5 years
    In the example above, I would not put the getter and setter public to avoid it being modified outside the class with no appropriate locking.
  • Joe
    Joe almost 5 years
    I would prefer to use a thread-safe dictionary rather than requiring developers to remember to lock. E.g. ConcurrentDictionary in .NET 4.0+ or .NET Core. Or consider using HttpRuntime.Cache or MemoryCache depending on your .NET version.
  • Aristos
    Aristos almost 5 years
    @Joe Depends from the design of your program. Most of the times you do not need to use static variables - When you use static variables on a web application that we have many different users - then is for a reason (some kind of cache for example) - but the next issue is that they are different value for each pool - So... its need some design to decide what you do.