以下代码/设计是否存在并发问题

时间:2012-06-06 07:07:58

标签: c# concurrency

我使用字典类实现了一个简单的缓存:

private Dictionary<int, byte[]> cache = new Dictionary<int, byte>();

public void SetPicture(int id, byte[] bytes)
{
    cache[id] = bytes;
}

public byte[] GetPicture(int id)
{
    if (cache.Contains(id)) {
        return cache[id];
    }
    return null;
}

SetPicture仅从单个后台线程调用。 (此后台线程正在从活动目录查询中更新用户配置文件图片。)

从多个其他线程(处理http请求的线程)调用GetPicture。

永远不会从缓存中删除项目。

这段代码线程安全吗?或者我是否需要在SetPicture中写入内部词典时阻止访问它?

2 个答案:

答案 0 :(得分:6)

不,它不安全;所有对字典的访问都需要同步,因为Dictionary<,>的内容保证读者对作者。另外,单独的contains / get检查是一个明显的线程争用。

选项:

  • 使用1.1风格Hashtable - 支持一个作家多个并发读者没有同步(这里的缺点就是你的密钥,{{1} },是一个值类型,因此需要加框; int在使用引用类型键时更具吸引力,例如Hashtable
  • 使用string
  • 使用ConcurrentDictionary<,>进行同步(假设读取比写入更常见)
  • 使用ReaderWriterLockSlim进行同步(假设非平凡的写入)

然而!如果您使用lock方法单独执行Hashtable / get - 请使用索引器。如果你得到Contains那就不存在了。否则你就有竞争条件。

答案 1 :(得分:2)

不是线程安全的。使用ConcurrentDictionary。如果无法找到条目,GetPicture也必须返回一些内容。