Asp.网络缓存模式
本文关键字:模式 缓存 网络 Asp | 更新日期: 2023-09-27 18:00:37
有很多关于线程安全缓存的文章,这里有一个例子:
private static object _lock = new object();
public void CacheData()
{
SPListItemCollection oListItems;
oListItems = (SPListItemCollection)Cache["ListItemCacheName"];
if(oListItems == null)
{
lock (_lock)
{
// Ensure that the data was not loaded by a concurrent thread
// while waiting for lock.
oListItems = (SPListItemCollection)Cache[“ListItemCacheName”];
if (oListItems == null)
{
oListItems = DoQueryToReturnItems();
Cache.Add("ListItemCacheName", oListItems, ..);
}
}
}
}
但是,此示例取决于对缓存的请求以及对缓存的重建。
我正在寻找一种将请求和重建分离的解决方案。下面是场景。
我有一个web服务,我想监控某些类型的错误。如果发生错误,我会创建一个监视器对象和缓存-它是可更新的,并在更新过程中相应地被锁定。到目前为止一切都很好。
在其他地方,我检查缓存对象的存在及其包含的数据。除了一个特定的场景外,这将直接开箱即用。
如果缓存对象正在更新,比如状态更改,我希望等待并获得最新信息,而不是当前信息,如果返回,则会过期。因此,对于我的获取代码,我需要检查对象当前是否正在创建/更新,如果是,请等待,然后重试。
正如我所指出的,有很多缓存锁定模式的例子,但我似乎找不到一个适用于这种情况的例子。如果有任何关于如何进行这项工作的想法,我们将不胜感激?
您可以使用两个锁来尝试以下代码。setter中的写锁非常简单,可以保护缓存不被多个线程写入。getter使用一个简单的双重检查锁。
现在,技巧在于Refresh()
方法,它使用与getter相同的锁。该方法使用锁,并在第一步中从缓存中删除列表。它将触发任何getter在第一次null检查中失败并等待锁定。该方法同时获取项,再次设置缓存并释放锁。当它返回到getter时,它再次读取缓存,现在它包含列表。
public class CacheData
{
private static object _readLock = new object();
private static object _writeLock = new object();
public SPListItemCollection ListItem
{
get
{
var oListItems = (SPListItemCollection) Cache["ListItemCacheName"];
if (oListItems == null)
{
lock (_readLock)
{
oListItems = (SPListItemCollection)Cache["ListItemCacheName"];
if (oListItems == null)
{
oListItems = DoQueryToReturnItems();
Cache.Add("ListItemCacheName", oListItems, ..);
}
}
}
return oListItems;
}
set
{
lock (_writeLock)
{
Cache.Add("ListItemCacheName", value, ..);
}
}
}
public void Refresh()
{
lock (_readLock)
{
Cache.Remove("ListItemCacheName");
var oListItems = DoQueryToReturnItems();
ListItem = oListItems;
}
}
}
如果不需要CacheData
实例,可以将方法和属性设置为静态。