MemoryCache is empty immediately after adding an object

I am having a weird issue with ASP.NET MemoryCaching in an ASP.NET MVC 3 application.

Every time an action is executed, I check whether its LoginInfo is actually stored in MemoryCache (the code has been simplified, but the kernel looks like this):

[NonAction] protected override void OnAuthorization(AuthorizationContext filterContext) { Boolean autorizzato = false; LoginInfo me = CacheUtils.GetLoginData(User.Identity.Name); if (me == null) { me = LoginData.UserLogin(User.Identity.Name); CacheUtils.SetLoginInfo(User.Identity.Name, me); } // Test if the object is really in the memory cache if (CacheUtils.GetLoginData(User.Identity.Name) == null) { throw new Exception("IMPOSSIBLE"); } } 

GetLoginInfo:

  public static LoginInfo GetLoginData(String Username) { LoginInfo local = null; ObjectCache cache = MemoryCache.Default; if (cache.Contains(Username.ToUpper())) { local = (LoginInfo)cache.Get(Username.ToUpper()); } else { log.Warn("User " + Username + " not found in cache"); } return local; } 

SetLoginInfo:

  public static void SetLoginInfo (String Username, LoginInfo Info) { ObjectCache cache = MemoryCache.Default; if ((Username != null) && (Info != null)) { if (cache.Contains(Username.ToUpper())) { cache.Remove(Username.ToUpper()); } cache.Add(Username.ToUpper(), Info, new CacheItemPolicy()); } else { log.Error("NotFound..."); } } 

The code is quite simple, but sometimes (completely randomly), immediately after adding LoginInfo to MemoryCache, this result is empty, just the added object is missing, so I got an exception.

I am testing this on both Cassini and IIS 7, it seems that it is not related to the reuse of AppPool (included in IIS 7), I tested several caching policies, but I can not get it to work

What am I missing / Failure?

PS: forgive me for my bad english

+8
asp.net-mvc
source share
3 answers

I believe that you are facing a problem that Scott Hanselman called a .NET 4 error. See Here: MemoryCache Empty: returns null after installation

+1
source share

When looking at the code for MemoryCache using decompilation, there is the following private function

 private void OnUnhandledException(object sender, UnhandledExceptionEventArgs eventArgs) { if (!eventArgs.IsTerminating) return; this.Dispose(); } 

Each MemoryCache module for the current Thread.GetDomain() domain Thread.GetDomain() an unhandled exception handler, so if your application ever had an exception that was not found that could be propagated on the website, it permanently stores MemoryCache and cannot be reused, this is especially true for IIS applications that apply to Windows applications that simply get rid of unused exceptions.

+3
source share

MemoryCache has a limited size. For Default, the instance is ist a heuristic value (according to MSDN ).

Have you tried setting the Priority property on the CacheItemPolicy instance to NotRemovable?

You may have a race condition because the Contains-Remove-Add sequence in SetLoginInfo is not atomic — try using Install instead.

Btw. you are working on a web application, so why not use System.Web.Caching.Cache instead?

+1
source share

All Articles