System.Runtime.Caching.MemoryCache vs HttpRuntime.Cache - are there any differences?

I am wondering if there are differences between MemoryCache and HttpRuntime.Cache , which one is preferable in ASP.NET MVC projects?

As far as I understand, both are thread safe, the API at first glance is more or less the same, so is there any difference when to use which?

+75
c # caching asp.net-mvc
Dec 04
source share
3 answers

HttpRuntime.Cache gets Cache for the current application.

The MemoryCache class MemoryCache similar to the ASP.NET Cache class.

The MemoryCache class has many properties and methods for accessing the cache, which you will be familiar with if you used the ASP.NET Cache class.

The main difference between HttpRuntime.Cache and MemoryCache is that the latter has been modified to make it usable by the .NET Framework applications, which are not ASP.NET applications.

For additional reading:

Update:

According to user reviews, sometimes the Jon davis blog does not work. I put the whole article as an image. Please look at that.

Note: If this is not clear, just click on the image. After that, it will open in the browser. Then click again to enlarge :)

enter image description here

+72
Dec 04
source

Here is an article by John Davis. To preserve readability, I now cut out the obsolete EntLib section, input, and output.




ASP.NET Cache

ASP.NET, or the System.Web.dll assembly, has a caching mechanism. It was never intended to be used outside the web context, but it can be used outside the Internet and it performs all of the above expiration actions in a hash table.

After cleaning Google, it seems that quite a few people who have discussed the built-in caching features in .NET are resorting to using the ASP.NET cache in their non-web projects. This is not the most affordable, most supported built-in caching system in .NET; .NET 4 has an ObjectCache, which I will get into later. Microsoft has always been convinced that the ASP.NET cache is not intended for use outside the Internet. But many people are still stuck in .NET 2.0 and .NET 3.5, and they need something to work, and this happens for many people, although MSDN clearly says:

Note. The Cache class is not intended to be used outside of ASP.NET applications. It was designed and tested for use in ASP.NET to provide caching for web applications. In other types of applications, such as console applications or Windows Forms applications, ASP.NET caching may not work correctly.

The class for the ASP.NET cache is System.Web.Caching.Cache in System.Web.dll. However, you cannot just update the Cache object. You must purchase it from System.Web.HttpRuntime.Cache.

 Cache cache = System.Web.HttpRuntime.Cache; 

Working with the ASP.NET cache is documented on MSDN here .

Pros:

  • Its built in .
  • Despite the syntax of .NET 1.0, its pretty simple .
  • When used in a web context, it is well tested . Outside of web contexts, as per Google’s search queries, it usually doesn’t cause problems, although Microsoft recommends abandoning it if you are using .NET 2.0 or newer.
  • You can be notified through the delegate when the item is deleted, which is necessary if you need to keep it alive and you cannot pre-set the priority of the items.
  • Individual elements have the flexibility of any (a), (b) or (c) expiration and deletion methods in the list of deletion methods at the top of this article. You can also associate an expiration action with a physical file.

Minuses:

  • It is not only static, but only one . You cannot create your own type with your static cache instance. You can only have one bucket for your entire application, period. You can wrap the bucket with your own wrappers that do things like pre-inject prefixes in keys and remove these prefixes when you pull out the key / value pairs. But there is only one bucket. Everything is concentrated together. This can be a real nuisance if, for example, you have a service that needs to cache three or four different data types separately. This should not be a big problem for simplest simple projects. But if a project has a significant degree of complexity due to its requirements, the ASP.NET cache will usually not be sufficient.
  • Elements can disappear, perforce . Many people know about this - I was not until I updated my knowledge about this cache implementation. By default, ASP.NET cache is designed to destroy elements when it "feels" itself. More specifically, see (C) in my cache table definition at the top of this article. If another thread in one process works on something completely different, and it flushes high-priority elements to the cache, then as soon as .NET decides that it needs some memory, it will begin to destroy some elements in the cache in accordance with their priorities, more low priorities. All the examples described here to add cache elements use the default priority, not the NotRemovable priority value, which does not allow it to be deleted for memory cleaning purposes, but will delete it anyway in accordance with the expiration policy. Peppering CacheItemPriority.NotRemovable in cache calls can be cumbersome, otherwise a shell is needed.
  • The key must be a string. If, for example, you cache data records in which records are entered in a long or integer, you must first convert the key to a string.
  • The syntax is deprecated . Its syntax is .NET 1.0, even more ugly than ArrayList or Hashtable. There are no generics, no IDictionary <> interface. It has no Contains () method, no key collection, no standard events; it only has a Get () method plus an index that does the same as Get (), returning null if there is no match, plus Add (), Insert () (redundant?), Remove () and GetEnumerator ().
  • Ignores the DRY principle for setting default behavior after expiration so that you can forget about them. You must explicitly specify the cache as you want the item you add to expire or be deleted each time you add an item.
  • It is not possible to access the cache items of the cached item, such as the timestamp when it was added. Encapsulation went a bit overboard, making it harder to use the cache when you are trying to determine in the code whether the cached item should be invalid with respect to another caching mechanism (i.e. Session dialing) or not.
  • Delete events are not displayed as events and should be monitored at the time of addition.
  • And if I did not say this, Microsoft clearly recommends against it outside the Internet. And if you're damned .NET 1.1, you should not use it with any confidence in stability at all outside the Internet, so don't worry.

.NET 4.0s ObjectCache / MemoryCache

Finally, Microsoft implemented the abstract ObjectCache class in the latest version of the .NET Framework and the MemoryCache implementation, which inherits and implements ObjectCache for in-memory purposes in settings other than websites.

System.Runtime.Caching.ObjectCache is located in the System.Runtime.Caching.dll assembly. This is an abstract class that declares basically the same .NET 1.0 style interfaces that are in the ASP.NET cache. System.Runtime.Caching.MemoryCache is an in-memory implementation of ObjectCache and is very similar to the ASP.NET cache with a few changes.

To add a sliding expiration item, your code would look something like this:

 var config = new NameValueCollection(); var cache = new MemoryCache("myMemCache", config); cache.Add(new CacheItem("a", "b"), new CacheItemPolicy { Priority = CacheItemPriority.NotRemovable, SlidingExpiration=TimeSpan.FromMinutes(30) }); 

Pros:

  • It is built-in and is now supported and recommended by Microsoft outside the Internet.
  • Unlike ASP.NET cache, you can instantiate a MemoryCache object.

    Note: it should not be static, but should be - Microsoft Recommendation (see yellow Warning) .

  • A few minor improvements were made compared to the ASP.NET cache interface, for example, the ability to subscribe to delete events without the need for presence when adding elements, redundant Insert () was deleted, elements can be added with a CacheItem object with an initializer that defines a caching strategy, and Contains () is added.

Minuses:

  • Still not fully enhancing DRY. From my little experience, you still cannot set the TimeSpan to expire once and forget about it. And frankly, although the policies in the example above, above, are more readable, this requires terrifying verbosity.
  • It still does not have a shared key; this requires a string as a key. Thus, you cannot store as long or int if you cache data records, unless you convert to a string.

Do it yourself: create it yourself

Actually, it’s quite simple to create a cache dictionary that performs an explicit or sliding ending. (This gets a lot more complicated if you want the items to be automatically deleted for memory cleaning purposes.) All you need to do:

  • Create a value container class, called either Expending or Expired, that will contain a value of type T, a TimeTamp property of type DateTime to store when the value has been added to the cache, and TimeSpan, which indicates how far from the time stamp at which the item should expire. For an explicit expiration, you can simply set the setter property, which sets the TimeSpan, given the date subtracted by the timestamp.
  • Create a class, let's call it ExpirableItemsDictionary, which implements IDictionary. I prefer to make it a general class defined by the consumer.
  • In the class created in # 2, add the dictionary> as a property and name it InnerDictionary.
  • An implementation if an IDictionary in a class created in # 2 should use an InnerDictionary to store cached elements. Encapsulation will hide the details of the caching method through instances of the type created in # 1 above.
  • Make sure the pointer (this []), ContainsKey (), etc. gently cleans expired items and deletes expired items before returning the value. Returns null in getters if the item has been deleted.
  • Use thread locks on all getters, setters, ContainsKey (), and especially when clearing expired items.
  • Raise an event whenever an item is deleted due to expiration.
  • Add an instance of System.Threading.Timer and set it during initialization to automatically delete expired items every 15 seconds. This is the same behavior as the ASP.NET cache.
  • You might want to add the AddOrUpdate () procedure, which pushes the sliding end, replacing the timestamp on the element container (expiring instance) if it already exists.

Microsoft must support its original projects because their user base has created a dependency on them, but that does not mean that they are good projects.

Pros:

  • You have full control .
  • It can enhance DRY by setting the default caching behavior, and then simply discarding key / value pairs without declaring caching data each time you add an item.
  • It can implement modern interfaces , namely IDictionary<K,T> . This makes it much easier to use because its interface is more predictable as a dictionary interface, and also makes it more accessible for helpers and extension methods that work with IDictionary <>.
  • Caching information can be unencapsulated , for example, exposing your InnerDictionary through a read-only public property, allowing you to write explicit unit tests against your caching strategy, and expand your underlying caching implementation with additional caching strategies that rely on it.
  • Although this is not necessarily a familiar interface for those who are already used to the ASP.NET cache .NET 2.0 style syntax or the caching application block, you can define an interface to look as if you want it to look.
  • Can use any type for keys. This is one of the reasons for creating generics. Not everything needs to be associated with a string.

Minuses:

  • It is not invented or approved by Microsoft , so it will not have the same quality guarantee.
  • Assuming that only the instructions described above are implemented, doesn’t it remove the elements to free memory in priority order (this is, in any case, a utility function for use in the cache anyway). BUY RAM, wherever you are using the cache, RAM is cheap).

Among all four of these options, this is my preference. I implemented this basic caching solution. So far this works fine, there are no known errors (please contact me with the comments below or in jon-at-jondavis, if any !!), and I intend to use it in all of my small projects that you need basic caching for. There he is:

Github Link: https://github.com/kroimon/ExpirableItemDictionary

Old link: ExpirableItemDictionary.zip

Worth mentioning: AppFabric, NoSQL, Et Al

Please note that the title of this blog article says “Simple caching” and not “Heavy-load cache.” If you want to get into difficult things, you should look at dedicated, large-scale solutions.

+14
Jan 24 '17 at 5:03 on
source

Memorycache is what it says cache stored in memory

HttpRuntime.Cache (see http://msdn.microsoft.com/en-us/library/system.web.httpruntime.cache(v=vs.100).aspx and http://msdn.microsoft.com/en -us / library / system.web.caching.cache.aspx ) is saved until what you configure in your application.

see, for example, "ASP.NET 4.0: Creating Custom Output Cache Providers" http://weblogs.asp.net/gunnarpeipman/archive/2009/11/19/asp-net-4-0-writing-custom-output -cache-providers.aspx

+3
Dec 04
source



All Articles