JBeckton
JBeckton

Reputation: 7111

Storing generic collection in System.Runtime.Caching - List<T>

I am using System.Runtime.Caching to store a List<MyType>. The problem is when I retrieve the collection it comes back as System.Object.

I have tried casting it back to List<MyType> with no luck.

if I try as I get a null

var siteNodes = _cacheManager.Get(Constants.CacheKeys.SiteNodesCacheKey) 
                as List<SiteNode>;

What is the proper way to store and retrieve my List<MyType> in cache?

I am using a cache manager class to access cache.

public void Add(string key, object data, int cacheTime,
                CacheEntryRemovedCallback callback)
    {
        _callback = callback;
        Add(key, data, cacheTime);
    }

public object Get(string key)
    {
        return Cache[key];
    }

var siteNodes = _cacheManager.Get(Constants.CacheKeys.SiteNodesCacheKey) 
                as List<SiteNode>;

Here is the method that adds to the cache

public void Add(string key, object data, int cacheTime, 
                CacheEntryRemovedCallback callback)
    {
        _callback = callback;
        Add(key, data, cacheTime);
    }

Here is the method that interacted with my cachemanager class.

private void CacheData(IEnumerable<object> data, string cacheKey)
    {
        if (_cacheManager.Contains(cacheKey))
        {
            _cacheManager.Remove(cacheKey);
        }

        _cacheManager.Add(cacheKey, data, DefaultCacheTime);

    }

The above method is the root of my problem, in an effort to keep my method reusable I have the first param as IEnumerable of object which is changing my data that is getting stored.

So I created the following override..

private void CacheData(List<SiteNode> data, string cacheKey)
    {
        if (_cacheManager.Contains(cacheKey))
        {
            _cacheManager.Remove(cacheKey);
        }

        _cacheManager.Add(cacheKey, data, DefaultCacheTime);

    }

Works like a charm!

Upvotes: 2

Views: 2539

Answers (2)

Simon
Simon

Reputation: 108

I've just been battling with the same error. Fix for me was to hard cast the CacheItem.Value, not the CacheItem, e.g:

return (IEnumerable<ObjType>)MyCacheItem.Value;

not...

return (IEnumerable<ObjType>)MyCacheItem;

(which caused the exception).

Upvotes: 2

zzing123
zzing123

Reputation: 54

You could to hard-cast it like this:

var siteNodes = (List<SiteNode>)_cacheManager.Get(Constants.CacheKeys.SiteNodesCacheKey);

But this will also break if the cache has expired the object. Instead, you first need to test if null (or do a contains to see if it's in cache), then hard-cast:

List<SiteNode> siteNodes;

object cached_site_nodes = _cacheManager.Get(Constants.CacheKeys.SiteNodesCacheKey);

if (null != cached_site_nodes)
{
   siteNodes = (List<SiteNode)cached_site_nodes;
}
else
{
   siteNodes = new List<SiteNode>();
}

By using the 'as' keyword you are effectively testing if it the underlying object is of type List, and it returns null since System.Runtime.Caching.ObjectCache has no idea what the type is when in the cache.

Upvotes: 2

Related Questions