Roy*_*mir 6 c# asp.net caching .net-4.0
Applicationasp.net中的类具有Lock支持线程安全的机制.
我们知道 - Application可以在全球范围内访问.
样品:
Application.Lock();
Application["MyCode"] = 21;
Application.UnLock();
Run Code Online (Sandbox Code Playgroud)
好.
但
也是Cache全局可访问的(并没有锁机制,也用于删除/添加项目)
那为什么Application有一个锁定机制而Cache不是?
Application是旧ASP技术的数据存储.它有一个全局锁.当您调用Application.Lock()对所有线程中的Application对象的所有访问都被阻止时.
另一方面Cache,ASP.NET引入的新对象允许您使用自己的锁定语义.您可以使用.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();
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,即使它们完全不相关,也会阻止对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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,只有需要访问的代码块myLockObject才会等待.访问的其他人Cache将并行运行就好了.如果getValue()抛出异常,则释放锁定而不会出现任何问题,让其他线程继续执行.