应用程序与缓存:锁定机制

时间:2012-04-22 14:00:31

标签: c# asp.net caching .net-4.0

asp.net中的Application类具有Lock机制来支持线程安全。

我们知道 - Application可以全局访问。

示例:

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

确定。

此外Cache是全局可访问的(并且没有锁定机制,也用于删除/添加项目)

那么为什么Application有锁定机制而Cache不具备?

1 个答案:

答案 0 :(得分:6)

Application是旧ASP技术中剩余的数据存储区。它有一个全局锁。当您调用Application.Lock()时,所有线程中对Application对象的所有访问都被阻止。

另一方面,ASP.NET引入的较新的Cache对象允许您使用自己的锁定语义。您可以使用.NET的lock语句来确保对Cache对象的线程安全访问,同时使Web应用程序尽可能保持并行。 lock语句更加安全,因为当您退出lock块时,可以保证释放锁定。应用程序对象不保证。缓存还提供自动过期机制,更适合缓存。它还可以基于依赖契约和可选优先级使密钥到期,这当然是Application对象所缺乏的。

我认为没有理由在Application对象上使用Cache

示例:假设您在缓存中有100个项目,并且您希望存储在缓存中的单个项目(如果尚未存在)。使用Application时,请执行以下操作:

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

在这种情况下,即使它们完全不相关,也会阻止对Application对象的所有访问。如果getValue()导致异常,则应用程序挂起,因为锁未被释放。你需要在try周围包裹finally .. Cache以确保它是安全的。

另一方面,使用if(Cache["someData"] == null) { lock(myLockObject) // or other shared lock for that single value { if(Cache["someData"] == null) { Cache["someData"] = getValue(); } } } 对象时,请执行以下操作:

myLockObject

在这种情况下,只有需要访问Cache的代码块才会等待。访问getValue()的其他人将并行运行。如果{{1}}抛出异常,则释放锁定而不会出现任何问题,让其他线程继续执行。