I am trying to write a caching class similar to the one in System.Web.Caching. The class will be a generic class but I am writing it with the the following application in mind:-
I have written an LDAP library for Active Directory that allows fast searching and creation of C# classes to represent the AD objects. 1) If searchA returns 200 objects and searchB returns 10 objects which have already been retrieved by searchA, then I want to ensure that the same object instance is used. 2) In certain cases, I want to be able to provide a read-ahead cache. An example of this is a speed-up of calculating nested memberships. (In a previous VB app, instead of recursing each nested membership down to its deepest level and then moving onto the next which involves thousands of small searches returning 1 or 2 objects, I made a list of all of the 'next- level' memberships and searched for them en-masse before continuing with the normal recursion - this way the objects I am looking for are already in the cache and no further access to the AD is required. The size of the searches increases (I have had a search expression of 500K before now!) but the number of searches is then limited to the deepest nesting level - typically 3 or 4) I thought that I could achieve this by storing the cached items in a wrapper that, as well as expiration date/access count/priority info etc., stores the object reference in a WeakReference object. This way, if the unused pre-cached items had been garbage collected to free memory, I could write the Cache classes retrieval code to silently remove the wrapper and inform the app that they are not in the cache and subsequent searches would look in the AD in the normal way. However, I found that even for relatively small searches of a couple of thousand items, when I inspected the cache I found that a large number had been collected by the GC if a strong reference was not present elsewhere. (I thought that a GC only occurred when memory was scarce - on a workstation at least - I know that server works differently). I am trying to think of a good solution to this and this is all I could come up with is this: - In the CachedItem wrapper, initially store the object to be cached directly in an object variable. - Have a System.Timers.Timer object in the cache instance that starts a maintenance event periodically. - The maintenance event goes through each of the wrappers and checks the stored reference. If it is not a WeakReference and sufficient time has passed since the object was first stored, then put the object reference into a WeakReference and store that instead. - Change the retrieval code to extract the real reference from the WeakReference if one is present. This way I can guarantee that a pre-cached item, regardless of whether a strong reference exists elsewhere in the application, will remain in the cache for at least a specified period of time. Can anyone offer a better way of doing this? Cheers Simon You can read messages from the Advanced DOTNET archive, unsubscribe from Advanced DOTNET, or subscribe to other DevelopMentor lists at http://discuss.develop.com.