I'm using MemoryCache
in ASP.NET and it is working well. I have an object that is cached for an hour to prevent fresh pulls of data from the repository.
I can see the caching working in debug, but also once deployed to the server, after the 1st call is made and the object is cached subsequent calls are about 1/5 of the time.
However I'm noticing that each new client call (still inside that 1 hour window - in fact just a minute or 2 later) seems to have the 1st call to my service (that is doing the caching) taking almost as long as the original call before the data was cached.
This made me start to wonder - is MemoryCache
session specific, and each new client making the call is storing it's own cache, or is something else going on to cause the 1st call to take so long even after I know the data has been cached?
Reviewing this a year later I found out some more information on my original post about the cache 'dropping' randomly. The MSDN states the following for the configurable cache properties
CacheMemoryLimitMegabytes
andPhysicalMemoryLimitPercentage
:Doing some decompiling and investigation, there are predetermined scenarios deep in the
CacheMemoryMonitor.cs
class that define the memory thresholds. Here is a sampling of the comments in that class on theAutoPrivateBytesLimit
property:It's not necessarily that the specific values are important as much as realizing to why cache is often used: to store large objects that we don't want to fetch over and over. If these large objects are being stored in the cache and the hosting environments memory threshold based on these internal calculations are exceeded, you may have the item removed from cache automatically. This could certainly explain my OP because I was storing a very large collection in memory on a hosted server with probably 2GB of memory running multiple apps in IIS.
There is an explicit override to setting these values. You can via configuration (or when setting up the
MemoryCache
instance) set theCacheMemoryLimitMegabytes
andPhysicalMemoryLimitPercentage
values. Here is modified sample from the following MSDN link where I set thephysicalMemoryPercentage
to 95 (%):From MSDN:
Reading that and doing some investigation in reflected code it is obvious that
MemoryCache
is just a simple class. You can useMemoryCache.Default
property to (re)use same instance or you can construct as many instances as you want (though recommended is as few as possible).So basically the answer lies in your code.
If you use
MemoryCache.Default
then your cache lives as long as your application pool lives. (Just to remind you that default application pool idle time-out is 20 minutes which is less than 1 hour.)If you create it using
new MemoryCache(string, NameValueCollection)
then the above mentioned considerations apply plus the context you create your instance in, that is if you create your instance inside controller (which I hope is not the case) then your cache lives for one requestIt's a pity I can't find any references, but ...
MemoryCache
does not guarantee to hold data according to a cache policy you specify. In particular if machine you're running your app on gets stressed on memory your cache might be discarded.If you still have no luck figuring out what's the reason for early cache item invalidation you could take advantage of
RemoveCallback
and investigate what is the reason of item invalidation.