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

Gar*_*wen 2 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;
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

Mar*_*ell 6

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

选项:

  • 使用1.1风格Hashtable- 支持一个编写器多个并发读取器而不 同步(这里的缺点是你的密钥int,是一个值类型,因此需要装箱; Hashtable使用引用类型键时更具吸引力,例如as string))
  • 用一个 ConcurrentDictionary<,>
  • 用于ReaderWriterLockSlim同步(假设读取比写入更常见)
  • 用于lock同步(假设非平凡的写入)

然而!如果您使用该Hashtable方法不要单独Contains/获取 - 只需使用索引器.如果你得到null它不是那里.否则你就有竞争条件.