Using an expiring cache in VCL.NET applications
When developing ASP.NET applications, it is common to take advantage of the System.Web.Caching.Cache class to cache items for later retrieval. It is also possible to have these cached items expire at a given time or after a specified period. You can even have an event raised when this expiration happens, which can be handy for instance if the cache contained a lookup table retrieved from a database, which could then be refreshed.
Well, don’t let the System.Web namespace put you off, but this class can also be used in VCL.NET and console applications. However, there is a slight trick to it, which may not be immediately obvious. If you simply attempted to instantiate a System.Web.Caching.Cache instance, you will soon find yourself getting NullReferenceExceptions as soon as you attempt to use the cache to add or retrieve items. A little digging in Reflector reveals that the Cache class uses the private System.Web.Caching.CacheInternal class to store the cached data, and that this class is not instantiated in the constructor. Instead it is set with a call to the private Cache.SetCacheInternal method.
A little further digging with Reflector, and we find our answer. It seems that the getter for the HttpRuntime.Cache property will check whether the Cache instance has been instantiated, and if not it will set off a chain of method calls across the appropriate classes to ensure that it is instantiated and initialized as expected. Armed with that insight, the next thing to do is to confirm that our cunning plan will indeed work. And the following console application should do the trick nicely :-
programCacheTest;{$APPTYPE CONSOLE}usesSystem.Web, System.Web.Caching, System.Threading;varlCache: Cache;beginlCache := Cache.Create;trylCache.Add('Foo','Bar',nil, DateTime.Now.AddSeconds(2), Cache.NoSlidingExpiration, CacheItemPriority.Normal,nil);exceptonNullReferenceExceptiondoConsole.WriteLine('Time to switch to Plan B');end;//Plan BlCache := HttpRuntime.Cache; lCache.Add('Foo','Bar',nil, DateTime.Now.AddSeconds(2), Cache.NoSlidingExpiration, CacheItemPriority.Normal,nil);ifAssigned(lCache['Foo'])thenConsole.WriteLine('Foo is in the cache'); Thread.Sleep(2000);ifnotAssigned(lCache['Foo'])thenConsole.WriteLine('Foo has now expired'); ReadLn;end.
Running the above code results in the following output :-
So it seems that our plan is indeed so cunning that we could stick a tail on it and call it a weasel. ![]()
Share This | Email this page to a friend
Posted by David Clegg on October 24th, 2007 under .NET, Delphi |


RSS Feed

Leave a Comment