c# - Ensuring thread safety with ASP.Net cache - a tale of two strategies -


i have code not thread safe:

public byte[] getimagebytearray(string filepath, string contenttype, rimgoptions options) {                    //our unique cache keys composed of both image's filepath , requested width     var cachekey = filepath + options.width.tostring();     var image = httpcontext.current.cache[cachekey];      //if there nothing in cache, need generate image, insert cache, , return     if (image == null)     {         rimggenerator generator = new rimggenerator();         byte[] bytes = generator.generateimage(filepath, contenttype, options);         cacheitem(cachekey, bytes);         return bytes;     }     //image exists in cache, serve up!     else     {         return (byte[])image;     } } 

my cacheitem() method checks see if max cache size has been reached, , if has, start removing cached items:

//if cache exceeds max allotment, remove items until falls below max while ((int)cache[cache_size] > rimgconfig.settings.profile.cachesize * 1000 * 1000) {     var entries = (dictionary<string, datetime>)cache[cache_entries];     var earliestcacheitem = entries.singleordefault(kvp => kvp.value == entries.min(d => d.value));     int length = ((byte[])cache[earliestcacheitem.key]).length;     cache.remove(earliestcacheitem.key);     cache[cache_size] = (int)cache[cache_size] - length; } 

since 1 thread remove item cache thread referencing it, can think of 2 options:

option 1: lock

lock (mylockobject) {     if(image == null){ **snip** } } 

option 2: assign shallow copy local variable

var image = httpcontext.current.cache[cachekey] != null ? httpcontext.current.cache[cachekey].memberwiseclone() : null; 

both of these options have overhead. first forces threads enter code block 1 @ time. second necessitates creating new object in memory of non-trivial size.

are there other strategies employ here?

to provide pure consistency of cache solution should lock resource while slowing down application.

in general, should try provide caching strategy, based on application logic.

  • check sliding window caching: while item older when time span - reduce locking of different threads - when have large spread of different cached items not sure used again.
  • consider using least used strategy: item least used should removed while reached max cache size - best serves while have multiple client hitting same part of cached content.

just check 1 more suites better type of bl , use it. not remove locking issue @ all, right choice remove racing conditions.

in order reduce shared resource between different threads, use read , write locks on each item , not on entire collection. boost performance well.

another point of consideration should kept in mind - if content of image same path changed physically on disk (different image saved same name) while having image cached there chance of mistakenly provide not relevant data.

hope helped.


Comments

Popular posts from this blog

database - VFP Grid + SQL server 2008 - grid not showing correctly -

jquery - Set jPicker field to empty value -

.htaccess - htaccess convert request to clean url and add slash at the end of the url -