Can(should?)Lazy <T>可以用作缓存技术吗?

Cri*_*ole 9 c# multithreading caching locking lazy-loading

我想使用.NETLazy<T>类来实现线程安全的缓存.假设我们有以下设置:

class Foo
{
    Lazy<string> cachedAttribute;

    Foo()
    {
        invalidateCache();
    }

    string initCache()
    {
        string returnVal = "";
        //CALCULATE RETURNVAL HERE
        return returnVal;
    }

    public String CachedAttr
    {
        get
        {
            return cachedAttribute.Value;
        }
    }

    void invalidateCache()
    {
        cachedAttribute = new Lazy<string>(initCache, true);
    }
}
Run Code Online (Sandbox Code Playgroud)

我的问题是:

  1. 这会起作用吗?
  2. 如何锁定必须工作?

我觉得我在invalidateCache附近的某个地方错过了一个锁,但对于我的生活,我无法弄清楚它是什么.

我确定这个地方有问题,我只是没弄明白.

[编辑]

好吧,看起来我是对的,有些东西我没想过.如果一个线程看到一个过时的缓存,那将是一件非常糟糕的事情,所以看起来"懒惰"不够安全.虽然这个属性被访问了很多,所以我正在进行预成熟优化,希望我能学到一些东西并且有一个模式可以在将来用于线程安全的缓存.我会继续努力.

PS:我决定让对象线程不安全,并且可以小心地控制对象的访问权限.

Jon*_*eet 9

好吧,它不是线程安全的,因为一个线程在失效后另一个线程看到新值后仍然可以看到旧值 - 因为第一个线程可能没有看到更改cachedAttribute.从理论上讲,这种情况可能永远存在,尽管它不太可能:)

使用Lazy<T>作为不变值的缓存对我来说似乎是一个更好的主意 - 更符合它的预期 - 但是如果你能够应对在另一个线程中任意长时间使用旧的"无效"值的可能性,我认为这没关系.