Archive for 'ASP.NET'

A better .NET cache (0)

October 8th, 2009 by Lloyd, under ASP.NET, Caching, Web Development.

I’ve been working on implementing caching into some of our products to increase efficiency and speed things up, however I came to a sticking point recently in that our products are often deployed to widely different platforms that don’t all offer the same feature set. This meant that caching on some systems didn’t work the same or at all on others.

Mulling over this today I decided upon a common cache engine that I could plug various cache providers into for available features allowing me to change which caching system to use depending on the platform without having to alter vast amounts of code.

I constructed a Cache class with static methods, a general outline of the class is as follows:

    public class Cache
    {

        public static void Initialize();
        public static void Uninitialize();

        public static bool Use;

        public static void RegisterProvider(ICacheProvider provider);
        public static void UnregisterProvider(ICacheProvider provider);

        public static object Get(string key);

        public static void Set(string key, object value);
        public static void Set(string key, object value, int minutes);
        public static void Set(string key, object value, DateTime dt);
        public static void Set(string key, object value, TimeSpan ts);

        public static void Unset(string key);

        public static bool Exists(string key);
        public static void Clear();

        public static ICacheProvider Default;
        public static ICacheProvider Empty;

    }

This provides a common way to access a cache rather than individualised access methods. For each individual cache system you write a class that implements ICacheProvider which interfaces between the Cache class and the underlying caching system.

The ICacheProvider interface looks like this:

    public interface ICacheProvider
    {

        void Initialize();
        void Unitialize();

        object Get(string key);

        void Set(string key, object value);
        void Set(string key, object value, int minutes);
        void Set(string key, object value, DateTime dt);
        void Set(string key, object value, TimeSpan ts);

        void Unset(string key);

        bool Exists(string key);
        void Clear();

        string Name
        {
            get;
        }

    }

As an example implementation take ASP.NET, which provides a cache as part of the HttpRuntime class. I can write an ICacheProvider to interface to it, such as:

    public class HttpRuntimeCacheProvider : CacheProvider
    {

        public override void Initialize()
        {
            // Do nothing...
        }

        public override void Unitialize()
        {
            // Do nothing...
        }

        public override object Get(string key)
        {
            return HttpRuntime.Cache.Get(key);
        }

        public override void Set(string key, object value)
        {
            DateTime expires = DateTime.UtcNow.AddMinutes(10);

            Set(key,value,expires);
        }

        public override void Set(string key, object value, DateTime dt)
        {
            DateTime expires = dt.ToUniversalTime();

            HttpRuntime.Cache.Insert(key,value,null,expires,System.Web.Caching.Cache.NoSlidingExpiration);
        }

        public override void Unset(string key)
        {
            HttpRuntime.Cache.Remove(key);
        }

        public override bool Exists(string key)
        {
            object value = Get(key);

            return (value != null);
        }

        public override void Clear()
        {
            List<string> keys = new List<string>();

            foreach(DictionaryEntry entry in HttpRuntime.Cache) keys.Add(entry.Key.ToString());
            foreach(string key in keys) HttpRuntime.Cache.Remove(key);
        }

        public override string Name
        {
            get {
                return "HttpRuntime";
            }
        }

    }

We can register and set as default using:

ICacheProvider provider = new HttpRuntimeCacheProvider();

Cache.RegisterProvider(provider);
Cache.Default = provider;

All future requests via Cache will now be handled by the ASP.NET cache.

In the included downloadable source code I’ve wrote providers for ASP.NET, MemCached and my own simple example provider. You can of course take this further and write one to use a database for example.

Below you’ll find the source code to download. I’ve used a custom build of a .NET MemCached client which I’ve also included a link to download. The original can be found here.

As always comments and suggestions welcome!

caching_engine.zip
30 KB
beit_memcached.zip
104 KB

Quick ASP.NET Caching (0)

July 17th, 2009 by Lloyd, under AJAX, ASP.NET, C#, Web Development.

One thing we’ve often found useful but underused is response caching, especially in the Web 2.0 world. There are a variety of options available and here’s a quick example of how to use the built in caching in ASP.NET.

For our example we’re going to cache for no more than 10 minutes, you can alter this as suits you. We’re also caching on an absolute time-scale but ASP.NET lets you also set a sliding time-scale.

public void ProcessRequest(HttpContext context)
{
        // Set Content Type
        context.Response.ContentType = "application/json";

        // Set key
        string key = "mydata";

        // Check cache for our hash
        object cache = context.Cache.Get(key);

        if (cache != null) {
            // Write out cached item
            context.Response.Write("/* From Cache */\r\n");
            context.Response.Write(cache.ToString());
            context.Response.Flush();

            // Return
            return;
        }

        // Get JSON from database or wherever
        string json = "{test:'Hello'}";

        context.Response.Write(json);
        context.Response.Flush();

        // Add response to cache
        context.Cache.Insert(
            key,
            json,
            null,
            DateTime.UtcNow.AddMinutes(10),
            System.Web.Caching.Cache.NoSlidingExpiration
        );
}

What happens is on the request we first check the cache for key. If we find that the cached item exists we retrieve this from the cache and dump that into the response.

If the item doesn’t exist however we generate the item content, be it a database call or whatever. Here this is mostly some kind of JSON so once we have the content we’d normally return we again dump that into the response but this time we also add it to the cache with the same key.

Caching is great for reducing load on databases and processing time, especially with commonly returned data such as dropdown lists who’s data rarely changes.

For further reading and a more fuller introduction to ASP.NET caching click here.

I’ve just finished up writing an article on implementing compression in ASP.NET web pages using nothing more than the .NET Framework on RemObjects Oxygene.

You can read it here.