In my application, I read some xml files into a list of objects (List<Thing>
) but I want to avoid having to hit the file system on each request. The data in the xml files rarely changes, so I'd like to cache it in some way. Either loading the data on application start or loading it lazy, is fine with me. I will need to be able to use the data throughout my app and run Linq queries against it, almost using it as a mini database in memory. I'll need to be able to change/update the data without it impacting the cached version, so copying the data to a local variable may be needed as well. How can I achieve this?
Asked
Active
Viewed 6,140 times
2

Brian David Berman
- 7,514
- 26
- 77
- 144
-
1Aren't you already caching it in the `List
`? – Mike Perrenoud May 29 '13 at 18:01 -
Right, but I want it to be available to all users between requests. – Brian David Berman May 29 '13 at 18:05
2 Answers
2
you can use the cache object for it.
myxmllist = HttpContext.Current.Cache["myxmllist"];
if (myxmllist == null)
{
//get xml from server
HttpContext.Current.Cache.Insert("myxmllist", myxmllist); // add it to cache
}

user1
- 1,063
- 1
- 8
- 28
-
Is that data structure thread safe (i.e. you don't need to `lock` when using it)? – Mike Perrenoud May 29 '13 at 18:09
-
1@MichaelPerrenoud Accessing the cache itself is safe. If you store an object inside of the cache that isn't designed to be used from multiple threads then you can have a problem. In this case it would be important to either use a collection from the `Concurrent` namespace, or ensure that you only ever read from data in the cache (which is thread safe) rather than writing to it. – Servy May 29 '13 at 18:11
-
@Servy, thanks a lot! I've always built my own. To clarify, when you say `or ensure that you only ever read from data in the cache` implies that you would load all the cache up front in `Global.asax` (common) **or** only *add* when something doesn't exist right? – Mike Perrenoud May 29 '13 at 18:13
-
1@MichaelPerrenoud No. It means you can set the value of the cache to be an entirely new list without problems, you just shouldn't get the list from the cache and then mutate the list. The list isn't designed to be mutated from multiple threads, or mutated while it is also being read from. – Servy May 29 '13 at 18:15
-
Is there a way to copy the cached value to a local variable to change/mutate? Most of this is working except I'm seeing the value get updated and persisted across multiple threads despite the fact that I assign the value to a local variable. – Brian David Berman May 29 '13 at 18:29
-
@BrianDavidBerman When using reference type objects, you can assign them to as many variables as you want (local or not), they will still all point to a single instance (memory location). If you need a true/deep copy, you need to write code that creates a new instance and assigns its data values from source instance. If there are subobjects that are reference types, they also must be new instances. – Igor May 29 '13 at 18:38
-
@Igor - In my question, I state "I will need to be able to use the data throughout my app and run Linq queries against it, almost using it as a mini database in memory. I'll need to be able to change/update the data without it impacting the cached version". Are you saying that this answer doesn't satisfy my question? – Brian David Berman May 29 '13 at 18:43
-
@BrianDavidBerman - you may be able to execute Linq operations against your memory storage (you need to check msdn for thread-safety of these operations). As far as change/update goes - you already discovered that it does not work the way you expected. – Igor May 29 '13 at 18:47
1
One of the main benefits of System.Runtime.Caching.MemoryCache
or System.Web.Caching.Cache
is the capability to set expiration policy on items you cache. If you are going to load data only once and keep it in memory for the life-time of the process, you may as well use a static class member which you create and fill with data in the static constructor of the same class. If your change/update operations should not affect data in memory, you need to load (or copy) the data into another instance of container and change (and possibly save) it.

Igor
- 15,833
- 1
- 27
- 32