c# - Object-cache generic locking -


i have memory cached object-cache, said cache can hold multiple types, , want add lock on said {t} whenever given {t} accessed.

my implementation:

    readonly static idictionary<type, list<object>> _cache = new concurrentdictionary<type, list<object>>();      private static list<object> findtypeincache(type type)     {         list<object> list;         if (_cache.trygetvalue(type, out list))         {             return list;         }         else         {             _cache[type] = new list<object>();         }          return new list<object>();     }      public static t findfirstby<t>(func<t, bool> predicate) t : class     {         // valid lock locking _cache[t] ? , not _cache whole?         lock (_cache[typeof(t)])         {             return findtypeincache(typeof(t)).cast<t>().where(predicate).firstordefault();         }     }      public static bool addorupdate<t>(func<t, bool> predicate, t entity) t : class     {         lock (_cache[typeof(t)])         {             // find type cache.             list<object> list = findtypeincache(typeof(t));              // old entity.             var e = list.cast<t>().where(predicate).firstordefault();              // if no old record exists no problem treat if new record.             if (e != null)             {                 // old record found removing it.                 list.remove(e);             }              // regardless if object existed or not add our cache.             list.add(entity);             _cache[typeof(t)] = list;         }     } 

is implementation correct only locking down _cache[t] , not entire _cache whole when accessed?

there's lot of things weird (or outright wrong) code.

first, you're using concurrentdictionary, you're not using as concurrent dictionary. example, initialize list, you'd use getoraddmethod:

private static list<object> findtypeincache(type type) {     return _cache.getoradd(type, () => new list<object>()); } 

simple , thread-safe :)

second, you're locking on _cache[type] - when there's no such type in cache. means keynotfoundexception.

third, code you're protecting lock reading. quite isn't enough - @ least, need protect writing same lock (especially tricky given point above), , depending on actual usage of return value, return value's mutations (and if indeed mutable, reads of mutable value well).

in other words, you've managed protect code doesn't need protecting (if use correct method update dictionary)! lock around where etc. might slightly, doesn't make list access safe.

all said, maybe there's better solution anyway. you're using cache using generic methods. why not make cache generic? way, you'll avoid using dictionary in first place, because each of generic types you're storing in dictionary own type - means can initialize list<t> in static constructor safely. locking can safely applied access specific generic cache rather "aggregate" cache have now.


Comments

Popular posts from this blog

javascript - Google App Script ContentService downloadAsFile not working -

javascript - Function overwritting -

php - Find a regex to take part of Email -