OK, I probably shouldn't have to make this post. As I keep making the mistake, there are only two possibilities: other people also make this mistake or I'm a unique idiot (as opposed to just another one).
When putting data into the ASP.NET Cache, make certain that your key is as unique as it needs to be. For example, you may need to read the data out of a local file for a control or other block of code. Here's the example from the docs (VB):
Public Sub AddItemToCache(sender As Object, e As EventArgs)
itemRemoved = false
onRemove = New CacheItemRemovedCallback(AddressOf Me.RemovedCallback)
If (IsNothing(Cache("Key1"))) Then
Cache.Add("Key1", "Value 1", Nothing, DateTime.Now.AddSeconds(60), TimeSpan.Zero, CacheItemPriority.High, onRemove)
End If
End Sub
So, what's the problem? Well, what happens if you have two vroots that might call this? Well, the key is the same, so those two vroots would share the data. If that's what you've intended, great. However, I think it is much more likely that each vroot will need it's own unique set of data. Similarly, do all users share this same data? In the cases where data should not be shared across vroots or users, you should select keys that are appropriate. Including the vroot, sessionid or other "uniquifier" in the key is probably a good idea.
I most recently made this mistake when writing a control that "would only ever be used in one vroot." By reflex, I wrote:
private String LoadAndCache(String filename) {
String result = null; String key = "Content";
result = Cache[key] as String;
if (null == result) {
try {
using (StreamReader reader = File.OpenText(filename)) {
result = reader.ReadToEnd();
}
} catch (Exception ex) {
//error opening file
Trace.Warn("Error Opening File " + ex.Message);
}
}
//and cache
Cache.Add(key, result,
new CacheDependency(filename),
Cache.NoAbsoluteExpiration,
Cache.NoSlidingExpiration,
CacheItemPriority.Normal, null);
return result;
}
Notice that the cache key is "Content". OK, as long as this only runs in a single vroot, or if everyone shares the content. Sadly, this was not the case. Testing created a number of vroots, and they were noticing that the data never changed. Ooops. The data should have been unique *per vroot*, as is often the case even if it should only ever run "in a single vroot." I changed the line bolded above to:
String key = String.Format("Content4{0}", GetVRoot());
Alternately, if each user should have received their own version of the content, you should concatenate with the SessionID. Don't assume that a simple string key for cache items will be enough for the life of the code.
Print | posted on Monday, April 24, 2006 10:49 PM