iisExpress local httpruntime.cache always null

961 views Asked by At

strange problem here. On local development in asp.net webforms (4.5 / 4.7) I am finding httpruntime.Cache always null even when properly set. I attempted it on another iis express workstation and found the same behavior, even with a tester single page web page. That same page in production IIS 7.5 works and is storing and delivering from cache. The code specifically is below, but I have tried a tester storing a simple string in httpruntime.Cache.

var cache = System.Runtime.Caching.MemoryCache.Default;
var luCacheKey = "lu_" + dsName;

var ic = HttpRuntime.Cache.Get(luCacheKey) as ICollection;
if (ic == null) {

and from the tester

var item = HttpRuntime.Cache.Get("x");
if (item == null)
{
    HttpContext.Current.Cache.Insert("x", "test" , null, DateTime.Now.AddHours(1), Cache.NoSlidingExpiration);
    Response.Write("added to cache<br>");
}
else {
    Response.Write("already in cache");
}

So, I am wondering if there is something perhaps in web.config that I could look at or is this expected IIS express behavior? Note, System.runtime.Caching does work properly.

var cache = System.Runtime.Caching.MemoryCache.Default;
var ic = cache[luCacheKey] as ICollection;
if (ic == null)
{
var filterCriteria = new BinaryOperator("LookupGroup", dsName, BinaryOperatorType.Equal);
var lookups = xpoSession.GetClassInfo(typeof(Lookups));
ic = xpoSession.GetObjects(lookups, filterCriteria, new SortingCollection(), 0, 0, false, false);
var cachePolicy = new System.Runtime.Caching.CacheItemPolicy() { AbsoluteExpiration = DateTime.Now + TimeSpan.FromMinutes(30) };
cache.Add(new System.Runtime.Caching.CacheItem(luCacheKey, ic), cachePolicy);
2

There are 2 answers

2
Wiktor Zychla On BEST ANSWER

You incorrectly add your object to the cache.

Instead of DateTime.Now follow the docs and put DateTime.UtcNow. This resolves a common issue where your machine is in a "non-zero" time zone which prevents the inner logic of the cache to manage your expirations correctly.

From the docs

To avoid possible issues with local time such as changes from standard time to daylight saving time, use UtcNow rather than Now for this parameter value.

https://msdn.microsoft.com/en-us/library/4y13wyk9(v=vs.110).aspx

0
Chris Suire On

Adding more information as follow up on why the behavior may change between servers.

This change in behavior may be caused by having .NET 4.7 installed on the machine. The article linked below says that Microsoft will fix this in the next version of .NET and in the next hotfix.

Quoting parts of the Microsoft page:

Symptoms:

Assume that you have Microsoft .NET Framework 4.7 installed on a computer. When you try to insert items into the Cache object by using the Cache.Insert (string, object, CacheDependency, DateTime, TimeSpan) Insert overload method, you may notice that the inserted Cache items expire much earlier or later than the specified DateTime (expiration time).

Cause:

The internal implementation of System.Web.Caching.Cache uses Coordinated Universal Time (UTC) time-stamp for absolute expiration. But this particular Cache.Insert (string, object, CacheDependecy, DateTime, TimeSpan) Insert overload method does not make sure whether the expiration time is converted to UTC. Therefore, expiration for items that are inserted into the Cache object by using this overload will occur earlier or later than expected, depending on the computer time zone difference from Greenwich Mean Time (GMT).

Workaround:

The temporary workaround for this issue is to use either the Cache.Add method or a different Cache.Insert overload method.

Resolution:

This issue will be fixed in the next version of the .NET Framework, and will also be available in the next hotfix for the .NET Framework 4.7.

References:

https://support.microsoft.com/en-us/help/4035412/fix-expiration-time-issue-when-you-insert-items-by-using-the-cache-ins

http://vimvq1987.com/2017/08/episerver-caching-issue-net-4-7/