0

To improve performance in my ASP.Net site I am caching collections of entities.

Below is some code that checks if the cache is populated, if it is then it returns the collection after performing "CacheClean" which resets certain properties so even if they were modified from another request they will be reset. If not then an entity query is ran and the cache is set.

       MemoryCache cache = MemoryCache.Default;
       List<MyControl> controlList = cache["ControlListByType" + TypeId] as List<MyControl>;

        if (controlList == null)
        {
            myDbContext.Configuration.ProxyCreationEnabled = false;
            myDbContext.Configuration.LazyLoadingEnabled = false;

            controlList = myDbContext.MyControls.AsNoTracking()                  
                .Include(c => c.ControlComboBoxes)
                .Include(c => c.ControlComments)                   
                .Include(c => c.ControlItems)               
                .Include(c => c.ControlType)
                .Include(c => c.ControlUploads)
                .Where(c => c.TypeId == TypeId).OrderBy(c => c.Position)
                .ToList();             

            cache["ControlListByType" + TypeId] = controlList;
        }
        else
            controlList.ForEach(c => c.CacheClean());

        return controlList;

My issue is that when processing the request these objects in the collection will be modified so if multiple users try to access the cache at the same time they could potentially overwrite each other and errors will occur or the View will be generated incorrectly.

So I am looking for a way to flag the cache entry as In use when accessed so that the cache is only used when populated and not in use, and then release it at the end of the request.

user2945722
  • 1,293
  • 1
  • 16
  • 35

1 Answers1

0

You may use lock to close the access for all thread until the first one haven't finished working with your cache. Only after it other threads will have access to your cache.

More information about it here:

How does lock work exactly?

https://msdn.microsoft.com/en-us/library/c5kehkcz.aspx

http://www.codeproject.com/Tips/788402/Monitor-and-Lock-in-Csharp

Community
  • 1
  • 1
Oleh Udovytskyi
  • 300
  • 1
  • 2
  • 10
  • I don't think lock will work as it is my understanding that it will cause other threads to wait where I wan't to check if it is "locked" and if it is then ignore the cache and retrieve the data from the database instead, so that there is no waiting. I would also need a way to lock it until the entire request is finished not just this block of code. – user2945722 Sep 15 '15 at 14:09
  • maybe you should check if the cache is locked http://stackoverflow.com/questions/12033725/c-sharp-how-to-detect-an-object-is-already-locked and if it so you may query your DB. But as you said it will also work only with the part of the code, not with the whole request. No new ideas yet... – Oleh Udovytskyi Sep 15 '15 at 14:23