James South
James South

Reputation: 10635

Caching image handler output strategies

Firstly I appreciate that this question could be seen as subjective but I strongly believe that there should be and probably is a definitive answer to my question.

At work we are currently implementing a strategy for dynamically resizing and serving images using a generic handler and the question of caching has become something of a contentious issue.

In my original implementation the resized image is cached in memory with a cache dependency based on the original image.

e.g

using (MemoryStream ms = new MemoryStream())
{
    imageEditor.Image.Save(ms, imageFormat);
    // Add the file to the cache.
    context.Cache.Insert(key, 
        ms.ToArray(), 
        new System.Web.Caching.CacheDependency(path)
        );
    imageEditor.Dispose();

    // Set the context headers and serve.
    SetHeaders(ms.GetHashCode(), context, responseType);
    context.Response.BinaryWrite(ms.ToArray());
}

This has it's downsides though.

  1. Every time the Application Pool Worker Process is recycled (every 1740 minutes by default) we'll lose anything that is in the cache.
  2. If there are a lot of images we could be in danger of overloading the system memory and causing an out of memory exception. (Does IIS prevent this by recycling the App pool if the usage hits a certain level?)

One of my colleagues has suggested that we implement a file caching system instead that saves the resized file and instead serves that file on subsequent requests which should (I don't know the intricacies of operating system IO caching memory management) reduce memory usage. Whilst this would allow us to persist the resized image across recycles I see a few major problems with that approach:

  1. We cannot track the original file any more so if someone uploads a new image of the same name our resized images will be incorrect.
  2. The fileserver becomes polluted over time with thousands of images
  3. Reading a file is slow compared to reading from memory. Especially if you are reading multiple files.

What would be the best overall approach? Is there a standard defined somewhere by Microsoft? The sites we build are generally very busy so we'd really like to get this right and to the best possible standard.

Upvotes: 1

Views: 766

Answers (3)

KV Prajapati
KV Prajapati

Reputation: 94645

You may use ASP.NET Generated Image. Interesting article by Scott Hanselman - ASP.NET Futures - Generating Dynamic Images with HttpHandlers gets Easier.

Upvotes: 0

Oliver
Oliver

Reputation: 11597

We have a similar system on my website. Regarding your objections to the file caching system:

1,2) On my site I have a single class through which all file saving/loading passes. You could implement something similar, that clears all the cached,resized images whenever a user uploads a new image. If you name the files in a predictable manner this isn't hard to do. If storage space is a concern for you, you could implement something to remove all cached images with a last access date that is too old.

3) This depends on how your sites work. My site has a vast number of images, so it isn't feasible to store them all in memory. If your site has fewer images, it might be the better solution.

Upvotes: 1

Andy Rose
Andy Rose

Reputation: 16984

This is not a complete answer to your question but, you shouldn't be able to cause a system of out memory exception by putting to much stuff into the cache. If system memory should start running low the application cache will automatically start removing the unimportant and seldom used items in order to avoid causing any memory issues.

Upvotes: 1

Related Questions