.net - Is there any purpose to Lazy<T> in this sample code? -


one of examples using task found on msdn (found here) seems rather odd. there reason lazy<t> class used here?

public class asynccache<tkey, tvalue> {     private readonly func<tkey, task<tvalue>> _valuefactory;     private readonly concurrentdictionary<tkey, lazy<task<tvalue>>> _map;      public asynccache(func<tkey, task<tvalue>> valuefactory)     {         if (valuefactory == null) throw new argumentnullexception("loader");         _valuefactory = valuefactory;         _map = new concurrentdictionary<tkey, lazy<task<tvalue>>>();     }      public task<tvalue> this[tkey key]     {                 {             if (key == null) throw new argumentnullexception("key");             return _map.getoradd(key, toadd =>                  new lazy<task<tvalue>>(() => _valuefactory(toadd))).value;         }     } } 

as lazy<task<tvalue>> created accessed. if it's being accessed using lazy<t> adds overhead , making example more confusing needs to. unless missing here?

you correct created accessed, important thing note you don't use object create.

dictionary's getoradd function acts lazy<t> lazythreadsafetymode.publicationonly means delegate pass in factory function may executed more once first finish returned callers.

the default behavior of lazy<t> lazythreadsafetymode.executionandpublication means first person call factory function obtain lock , other callers have wait till factory function finishes before continuing on.

if reformat method becomes little more clear.

public task<tvalue> this[tkey key] {         {         if (key == null)             throw new argumentnullexception("key");         var cacheitem = _map.getoradd(key, toadd =>                               new lazy<task<tvalue>>(() => _valuefactory(toadd)));         return cacheitem.value;     } } 

so if 2 threads both call this[tkey key] @ same time , both reach getoradd no value in dictionary passed in key new lazy<task<tvalue>>(() => _valuefactory(toadd)) will executed twice, first 1 complete gets returned both calls. not big deal because _valuefactory not executed yet , expensive portion, doing making new lasy<t>.

once getoradd call returns working same single object, when .value called, uses executionandpublication mode , block other calls .value until _valuefactory finshes executing.

if did not use lazt<t> _valuefactory have gotten executed multiple times before single result returned.


Comments