Reputation: 148524
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 ?
Upvotes: 6
Views: 2700
Reputation: 47660
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.
Upvotes: 6