MemoryCache.Set返回移除缓存项 [英] MemoryCache.Set return removed cache item

查看:178
本文介绍了MemoryCache.Set返回移除缓存项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的是.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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆