Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Application vs Cache : Lock mechanism

The Application class in asp.net has Lock mechanism to support thread safety.

As we know - the Application can be accessed globally.

sample :

Application.Lock();
Application["MyCode"] = 21;
Application.UnLock();

ok.

but

Also the Cache is globally Accessible ( and doesnt have lock mechanism and also used to remove/ add items)

so why does Application has a lock mechanism and Cache Doesn't ?

like image 389
Royi Namir Avatar asked Apr 22 '12 14:04

Royi Namir


1 Answers

Application is a datastore remaining from old ASP technology. It has a single global lock. When you call Application.Lock() all accesses to Application object in all threads are blocked.

On the other hand the newer Cache object which was introduced with ASP.NET allows you to use your own locking semantics. You can use .NET's lock statement to ensure thread-safe access to Cache object while keeping your web application as parallel as possible. The lock statement is much safer since lock is guaranteed to be released when you exit a lock block. Application object doesn't guarantee that. Cache also provides auto-expire mechanisms which is much more suited for, well, a cache. It can also expire keys based on dependency contracts and optional priorities which of course Application object lacks.

I see no reason to use Application over Cache object.

Example: Let's say you have hundred items in the cache and you have a single item you want to store in the cache if it's not already there. When you use Application, you do this:

if(Application["someData"] == null) 
{
    Application.Lock();
    if(Application["someData"] == null) 
    {
        Application["someData"] = getValue(); //a very long time consuming function
    }
    Application.Unlock();
}

In this scenario all accesses to Application object are blocked even if they are completely irrelevant. And in case getValue() causes an exception your Application is hung because the lock is not released. You need to wrap a try..finally around that to make sure it's safe.

On the other hand when using a Cache object, you do this:

if(Cache["someData"] == null)
{
    lock(myLockObject)  // or other shared lock for that single value
    {
        if(Cache["someData"] == null)
        {
            Cache["someData"] = getValue();
        }
    }
}

In this case only code blocks which require access to myLockObject would be waiting. Others which access to Cache would be running in parallel just fine. And in case getValue() throws an exception your lock is released without any issues letting other threads continue execution.

like image 144
Sedat Kapanoglu Avatar answered Oct 23 '22 07:10

Sedat Kapanoglu