Какъв е препоръчителният начин за премахване на голям брой елементи от екземпляр на MemoryCache?
Въз основа на дискусията около този въпрос изглежда, че предпочитаният подход е да се използва един кеширайте за цялото приложение и използвайте именни пространства за ключове, за да позволите множество логически типове елементи да бъдат кеширани в един и същи екземпляр.
Използването на един екземпляр на кеша обаче оставя проблема с изтичане (премахване) на голям брой елементи от кеша. Особено в случай, че всички елементи от определен логически тип трябва да са с изтекъл срок.
В момента единственото решение, което намерих, се основаваше на отговора на този въпрос, но е наистина не е много добър от гледна точка на производителността, тъй като ще трябва да изброите всички ключове в кеша и да тествате пространството от имена, което може да отнеме доста време!
Единственото заобиколно решение, което измислих в момента, е да създам тънка обвивка за всички обекти в кеша с номер на версия и всеки път, когато има достъп до обект, да го изхвърля, ако кешираната версия не съвпада с текущата версия. Така че винаги, когато трябва да изчистя всички елементи от определен тип, бих увеличил номера на текущата версия, правейки всички кеширани елементи невалидни.
Заобикалянето по-горе изглежда доста солидно. Но не мога да не се запитам дали няма по-прост начин да постигнем същото?
Това е текущата ми реализация:
private class MemCacheWrapper<TItemType>
where TItemType : class
{
private int _version;
private Guid _guid;
private System.Runtime.Caching.ObjectCache _cache;
private class ThinWrapper
{
public ThinWrapper(TItemType item, int version)
{
Item = item;
Version = version;
}
public TItemType Item { get; set; }
public int Version { get; set; }
}
public MemCacheWrapper()
{
_cache = System.Runtime.Caching.MemoryCache.Default;
_version = 0;
_guid = Guid.NewGuid();
}
public TItemType Get(int index)
{
string key = string.Format("{0}_{1}", _guid, index);
var lvi = _cache.Get(key) as ThinWrapper;
if (lvi == null || lvi.Version != _version)
{
return null;
}
return lvi.Item;
}
public void Put(int index, TItemType item)
{
string key = string.Format("{0}_{1}", _guid, index);
var cip = new System.Runtime.Caching.CacheItemPolicy();
cip.SlidingExpiration.Add(TimeSpan.FromSeconds(30));
_cache.Set(key, new ThinWrapper(item, _version), cip);
}
public void Clear()
{
_version++;
}
}