MemoryCache.Set返回移除缓存项 [英] MemoryCache.Set return removed cache item
问题描述
我使用的是.NET 4.0 的MemoryCache
>,我想添加或更换以线程安全的方式缓存中的现有项目,但我也想知道我是否已经取代了现有项目或添加一个新的。
这是我所知道的,的 设置
方法用于在原子替换项目的目的缓存如果它存在,而 AddOrGetExisting
方法将原子得到我现有的项目,而无需更换它。
不过,设置方法不返回被更换的部件,它只是替换它。它可以removed事件挂接到的 CacheItemPolicy
的项目,但很难匹配起来与它换成新的项目。
我可以用下面的方法近似,但它似乎有点重(因为要求缓存从根本上增加两倍的项目),我想问如果有人知道更简单的方法来做到这一点。
公共对象SetAndGetExisting(字符串键,对象的值,CacheItemPolicy政策,串regionName = NULL)
{
锁定(_cacheLock)
{
VAR现有= _cache.AddOrGetExisting(键,值,政策,regionName);如果(现!= NULL)
{
_cache.Set(键,值,政策,regionName);
返回存在;
}
返回NULL;
}
}
在想着它,在你的榜样,你无论更新它,所以 AddOrGetExisting
是不是最好的,正如你所说,你反正以后设置它。下面就简单的实现,我觉得符合你要求什么。如果我错了,请让我知道!
公共类MemoryCacheWithEvents
{
私有静态的MemoryCache _cache =新的MemoryCache(myCache);
私有静态对象_syncLock =新的对象();
公共事件处理程序和LT; CacheChangeEventArgs> AddingCacheItem;
公共事件处理程序和LT; CacheChangeEventArgs> UpdatingCacheItem;
公共对象GetAndSetExisting(字符串键,对象的值,CacheItemPolicy政策,串regionName = NULL)
{
锁(_syncLock)
{
VAR cacheItem =新cacheItem(键,值,regionName);
VAR现有= _cache.GetCacheItem(键,NULL);
如果(现有== NULL)
{
OnAddingCacheItem(新CacheChangeEventArgs(NULL,cacheItem));
}
,否则
{
OnUpdatingCacheItem(新CacheChangeEventArgs(现有cacheItem));
}
_cache.Set(cacheItem,政策);
返回存在;
}
}
公共虚拟无效OnAddingCacheItem(CacheChangeEventArgs EventArgs的){
VAR处理器= AddingCacheItem;
如果(处理!= NULL)
{
处理器(这一点,EventArgs的);
}
}
公共虚拟无效OnUpdatingCacheItem(CacheChangeEventArgs EventArgs的){
VAR处理器= UpdatingCacheItem;
如果(处理!= NULL)
{
处理器(这一点,EventArgs的);
}
}
}
公共类CacheChangeEventArgs:EventArgs的
{
公共对象OldCacheItem {搞定;组; }
公共对象NewCacheItem {搞定;组; }
公共CacheChangeEventArgs(对象oldCacheItem,对象newCacheItem)
{
this.OldCacheItem = oldCacheItem;
this.NewCacheItem = newCacheItem;
}
}
I am using the .NET 4.0 MemoryCache
class, and I want to add or replace an existing item in the cache in a thread-safe manner, but I also want to know whether I have replaced an existing item or added a new one.
From what I can tell, the Set
method is intended for the purpose of atomically replacing an item in the cache if it exists, whereas the AddOrGetExisting
method will atomically get me the existing item without replacing it.
However, the Set method doesn't return the item that was replaced, it just replaces it. It is possible to hook up a removed event to the CacheItemPolicy
for items, but hard to match that up with the new item that replaced it.
I can approximate it with the following method, but it seems a bit heavy (because of asking the cache to essentially add an item twice) and I wanted to ask if someone knows an easier way to do it.
public object SetAndGetExisting(string key, object value, CacheItemPolicy policy, string regionName = null)
{
lock (_cacheLock)
{
var existing = _cache.AddOrGetExisting(key, value, policy, regionName);
if (existing != null)
{
_cache.Set(key, value, policy, regionName);
return existing;
}
return null;
}
}
After thinking about it, in your example, you are updating it regardless, so AddOrGetExisting
isn't the best, as you mentioned, you are setting it later anyway. Below it a simple implementation that I think fits what you are asking for. If I am wrong, please let me know!
public class MemoryCacheWithEvents
{
private static MemoryCache _cache = new MemoryCache("myCache");
private static object _syncLock = new object();
public EventHandler<CacheChangeEventArgs> AddingCacheItem;
public EventHandler<CacheChangeEventArgs> UpdatingCacheItem;
public object GetAndSetExisting(string key, object value, CacheItemPolicy policy, string regionName = null)
{
lock (_syncLock)
{
var cacheItem = new CacheItem(key, value, regionName);
var existing = _cache.GetCacheItem(key, null);
if (existing == null)
{
OnAddingCacheItem(new CacheChangeEventArgs(null, cacheItem));
}
else
{
OnUpdatingCacheItem(new CacheChangeEventArgs(existing, cacheItem));
}
_cache.Set(cacheItem, policy);
return existing;
}
}
public virtual void OnAddingCacheItem(CacheChangeEventArgs eventArgs){
var handler = AddingCacheItem;
if (handler != null)
{
handler(this, eventArgs);
}
}
public virtual void OnUpdatingCacheItem(CacheChangeEventArgs eventArgs){
var handler = UpdatingCacheItem;
if (handler != null)
{
handler(this, eventArgs);
}
}
}
public class CacheChangeEventArgs : EventArgs
{
public object OldCacheItem { get; set; }
public object NewCacheItem { get; set; }
public CacheChangeEventArgs(object oldCacheItem, object newCacheItem)
{
this.OldCacheItem = oldCacheItem;
this.NewCacheItem = newCacheItem;
}
}
这篇关于MemoryCache.Set返回移除缓存项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!