Microsoft CacheManager Contains vs Getdata
In Microsoft.Practices.EnterpriseLibrary.Caching, GetData is used to get data from the cache and Contains checks whether the key exists in the cache. Ideally if Contains(key) returns true than GetData(key) should returns data from the cache associated with the key. But somehow it works in the different condition. In the below code block Contains(key) returns true but the block returns null.
if (cacheManager.Contains(key)) { return cacheManager.GetData(key); }
Why ?
Before returning the cached value, the GetData method performs a check to see if the CacheItem has expired. If it has expired, the CacheItem is removed from the cache and null is returned. However, the call to Contains will return true because the CacheItem is in the cache even though it’s expiration may have elapsed. This seems to be by design. With that in mind, it would be wise not to cache a null value to represent no data since you would not be able to discern an expired CacheItem from an actual cached value of null.
This scenerio is basically a race condition in which the items are dropping out of the cache between the Contains check and the GetData retrieval..
Summary
One of the reasons that .Contains can come back as true and .GetData can return a null is that .GetData goes through the whole expiration system (it seems to only return data which isn’t expired) and .Contains doesn’t check to see if it’s content is expired.
Conclusion
In order to get out from the null exception its better to check the null value before we are returning.
and if it null we first add the the key into cache and then return it.
Suggestion
Instead of using Contains in the if block we can directly get the data and check whether it is null or not if not null than retrieve it from cache.
if (cacheManager.GetData(key) != null)
{
return cacheManager.GetData(key);
}