Can(should?) Lazy<T> be used as a caching technique? Can(should?) Lazy<T> be used as a caching technique? multithreading multithreading

Can(should?) Lazy<T> be used as a caching technique?


Well, it's not thread-safe in that one thread could still see the old value after another thread sees the new value after invalidation - because the first thread could have not seen the change to cachedAttribute. In theory, that situation could perpetuate forever, although it's pretty unlikely :)

Using Lazy<T> as a cache of unchanging values seems like a better idea to me - more in line with how it was intended - but if you can cope with the possibility of using an old "invalidated" value for an arbitrarily long period in another thread, I think this would be okay.


cachedAttribute is a shared resource that needs to be protected from concurrent modification.

Protect it with a lock:

private readonly object gate = new object();public string CachedAttr{    get    {        Lazy<string> lazy;        lock (gate)                         // 1. Lock        {            lazy = this.cachedAttribute;    // 2. Get current Lazy<string>        }                                   // 3. Unlock        return lazy.Value                   // 4. Get value of Lazy<string>                                            //    outside lock    }}void InvalidateCache(){    lock (gate)                             // 1. Lock    {                                       // 2. Assign new Lazy<string>        cachedAttribute = new Lazy<string>(initCache, true);    }                                       // 3. Unlock}

or use Interlocked.Exchange:

void InvalidateCache(){    Interlocked.Exchange(ref cachedAttribute, new Lazy<string>(initCache, true));}

volatile might work as well in this scenario, but it makes my head hurt.