Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is a Cache of type T possible?

Tags:

c#

caching

Can we avoid casting T to Object when placing it in a Cache?

WeakReference necessitate the use of objects. System.Runtime.Caching.MemoryCache is locked to type object.

Custom Dictionaries / Collections cause issues with the Garbage Collector, or you have to run a Garbage Collector of your own (a seperate thread)?

Is it possible to have the best of both worlds?


I know I accepted an answer already, but using WeakReference is now possible! Looks like they snuck it into .Net 4.

http://msdn.microsoft.com/en-us/library/gg712911(v=VS.96).aspx


an old feature request for the same.

http://connect.microsoft.com/VisualStudio/feedback/details/98270/make-a-generic-form-of-weakreference-weakreference-t-where-t-class

like image 947
sgtz Avatar asked Jul 08 '11 10:07

sgtz


2 Answers

There's nothing to stop you writing a generic wrapper around MemoryCache - probably with a constraint to require reference types:

public class Cache<T> where T : class
{
    private readonly MemoryCache cache = new MemoryCache();

    public T this[string key]
    {
        get { return (T) cache[key]; }
        set { cache[key] = value; }
    }

    // etc
}

Obviously it's only worth delegating the parts of MemoryCache you're really interested in.

like image 75
Jon Skeet Avatar answered Sep 29 '22 10:09

Jon Skeet


So you basically want to dependanct inject a cache provider that only returns certain types? Isn't that kind of against everything OOP?

The idea of the "object" type is that anything and everything is an object so by using a cache that caches instances of "objects" of type object you are saying you can cache anything.

By building a cache that only caches objects of some predetermined type you are limiting the functionality of your cache however ...

There is nothing stopping you implementing a custom cache provider that has a generic constraint so it only allows you cache certain object types, and this in theory would save you about 2 "ticks" (not even a millisecond) per retrieval.

The way to look at this is ...

What's more important to me:

  1. Good OOP based on best practise
  2. about 20 milliseconds over the lifetime of my cache provider

The other thing is ... .net is already geared to optimise the boxing and unboxing process to the extreme and at the end of the day when you "cache" something you are simply putting it somewhere it can be quickly retrieved and storing a pointer to its location for that retrieval later.

I've seen solutions that involve streaming 4GB XML files through a business process that use objects that are destroyed and recreated on every call .. the point is that the process flow was important not so much the initialisation and prep work if that makes sense.

How important is this casting time loss to you? I would be interested to know more about scenario that requires such speed.

As a side note: Another thing i've noticed about newer technologies like linq and entity framework is that the result of query is something that is important to cache when the query takes a long time but not so much the side effects on the result.

What this means is that (for example): If i was to cache a basic "default instance" of an object that uses a complex set of entity queries to create, I wouldn't cache the resulting object but the queries.

With microsoft already doing the ground work i'd ask ... what am i caching and why?

like image 35
War Avatar answered Sep 29 '22 09:09

War