Skip to main content
 首页 » 编程设计

c#之锁定自加载缓存

2024年01月29日27shihaiming

我正在用 C# 实现一个简单的缓存,并试图让它可以从多个线程访问。在基本的阅读案例中,这很简单:

var cacheA = new Dictionary<int, MyObj>(); // Populated in constructor 
 
public MyObj GetCachedObjA(int key) 
{ 
    return cacheA[key]; 
} 

我相信,这是完全线程安全的。但我也想让它自动加载。也就是说,如果缓存未在访问时填充,它会在满足访问请求之前填充缓存。

Dictionary<int, MyObj> cacheB = null; 
 
public MyObj GetCachedObjB(int key) 
{ 
    if (cacheB == null) 
    { 
        PopulateCacheB(); 
    } 
    return cacheB[key]; 
} 
 
private void PopulateCacheB() 
{ 
    cacheB = new Dictionary<int, MyObj>(); 
    foreach (MyObj item in databaseAccessor) 
    { 
        cacheB.Add(item.Key, item); 
    } 
} 

这不是线程安全的,因为一个线程可以在 cacheB 被实例化之后但在它被完全填充之前访问 GetCachedObjB,如果另一个线程正在填充它的话。 那么在 cacheB 上执行锁定以使缓存线程安全的最佳方法是什么?

请您参考如下方法:

像这样: http://devplanet.com/blogs/brianr/archive/2008/09/26/thread-safe-dictionary-in-net.aspx

您的第一个示例根本不是线程安全的。如果某人恰好在另一个人从 map 中获取某些内容时插入怎么办?插入可能会改变字典,这意味着读取它可能会访问损坏的状态