Am using following .net code to add objects to cache:
public static void Add<T>(string key, T dataToCache)
{
try
{
ApplicationLog.Instance.WriteInfoFormat("Inserting item with key {0} into Cache...", key);
HttpRuntime.Cache.Insert(
key,
dataToCache,
null,
DateTime.Now.AddDays(7),
System.Web.Caching.Cache.NoSlidingExpiration);
}
catch (Exception ex)
{
ApplicationLog.Instance.WriteException(ex);
}
}
and here is my code to retrieve values from cache:
public static T Get<T>(string key)
{
try
{
if (Exists(key))
{
ApplicationLog.Instance.WriteInfoFormat("Retrieving item with key {0} from Cache...", key);
return (T)HttpRuntime.Cache[key];
}
else
{
ApplicationLog.Instance.WriteInfoFormat("Item with key {0} does not exist in Cache.", key);
return default(T);
}
}
catch(Exception ex)
{
ApplicationLog.Instance.WriteException(ex);
return default(T);
}
}
public static bool Exists(string key)
{
bool retVal = false;
try
{
retVal= HttpRuntime.Cache[key] != null;
}
catch (Exception ex)
{
ApplicationLog.Instance.WriteException(ex);
}
return retVal;
}
But i find that after every 2 minutes or so,the cached object value is getting set to null resulting in pulling that value from database again.
What am i missing here?
Well first of all your access isn't synchronized so that's a great source of problems. Reading from the HttpRuntime Cache is guarantied to be thread safe so you should really try reading your item as your first step on each and every cache operation.
Between checking if
Exists
and actually retrieving the item lots of things can happen (such as your item not beeing there anymore). You should get a handle of the item you're looking for, and if it isn't there provide thread-safe insert by fetching it from your persistent data store.So your
Add
logic would get inside yourGet
IF the data isn't there. There's nothing fundamentally wrong in providing separateAdd
logic and you should measure the cost of hitting the database multiple times compared to blocking further requests for that specific piece of data.Depending on your expiration policy you'll get your data in memory and provide fast & synchronized access to it, but as I said, measure it and adjust it to your needs. In your business logic after updating your item and properly saving it to your persistent store, just remove it from cache and the next call to your
Get
will fetch it again.When you say every two minutes the value inserted is set to null, does that mean just the item you're interested in or every single item in the cache?
I ask this because the cache only exists as long as the application is running. If the application is restarted, the cache goes away. This would explain the behavior if everything goes away every 2 minutes. In that case you have a different problem on your hands: why does the application restart every 2 minutes.
If it's only SOME items then it could be a memory issue. The cache cleans itself up in response to low memory. I believe there's a way to set priority on values inserted. But this should only be a problem when you're low on memory.
If this still doesn't solve your problem, there is a way to discover why an item is being removed. It is explained here.
It could be because memory is running low, the cache will automatically kill off items in the cache when memory is becoming scarce, There is an optional parameter to set the priority of items in the cache if you want one item to be cleared before another.