MemoryCache with a certain number of elements

Does MemoryCache have functions for caching a fixed number of items?

eg. We are only interested in the elements of the cache 2000 from the database. Continuing to add items to the cache, if the specified number of items is exceeded, the oldest of them can be deleted.

If not, do we need to use a different thread to keep the house regularly?

+4
source share
2 answers

There is nothing built-in that will limit the number of objects. Instead, it checks how much memory is being used and compares it with CacheMemoryLimit . If the CacheMemoryLimit value CacheMemoryLimit exceeded, it will reduce the old elements. You can also set items to automatically expire after a certain time through CacheItemPolicy .

These approaches make sense if you really use it as a memory cache. In other words, if you are worried about the trade-off between the memory limit and the cost of retrieving data, these are great ways to determine when to exit the cache. So ask yourself:

Am I really trying to use this as a MemoryCache? Why don't I care if only 2,000 items are loaded from the database?

If you are concerned about running out of memory or if you are worried that items are out of date, there are other (better) ways to manage your cache than specifying the number of objects. If you have a special reason for storing a certain number of objects in a data structure, consider using another class.

+7
source

Another option would be to create a new MemoryCache provider that manages object restrictions for you. This will result in overriding some of the MemoryCache methods, such as adding and removing, and automatically dropping items after reaching an arbitrary limit (for example, 2000 objects).

One such implementation may look like this:

 public class ObjectLimitMemoryCache : MemoryCache { private const int ObjectLimit = 2000; private const string IndexKey = "ObjectLimitIndexKey"; public ObjectLimitMemoryCache(string name, NameValueCollection config) : base (name, config) { } new public static ObjectLimitMemoryCache Default { get { return new ObjectLimitMemoryCache(Guid.NewGuid().ToString(), new NameValueCollection());}} public override bool Add(string key, Object value, DateTimeOffset absoluteExpiration, string region = null) { try { var indexedKeys = (List<string>)(base.Get(IndexKey) ?? new List<string>()); if (base.Add(key, value, absoluteExpiration)) { string existingKey; if (string.IsNullOrEmpty(existingKey = indexedKeys.FirstOrDefault(x=>x == key))) { indexedKeys.Add(key); } if (base.GetCount() > ObjectLimit) { base.Remove(indexedKeys.First()); indexedKeys.RemoveAt(0); } base.Add(IndexKey, indexedKeys, new DateTimeOffset(DateTime.Now.AddHours(2))); return true; } return false; } catch { //Log something and other fancy stuff throw; } } } 

This is unverified code and is intended only to illustrate an example implementation of MemoryCache. Good luck

+1
source

Source: https://habr.com/ru/post/1433042/


All Articles